记一次前后端项目Nginx代理出现的“405”问题
事情的起因是这样的: 因为好久没有写前端代码了对前端打包部署这块有点抵触 公司的有个小项目是前端vue+后端springboot实现的
在部署的时候 通过nginx反向代理去实现跨域(这块nginx一直都是简单的使用 也没有过深的了解 包括之前也用过nginx+memache实现的灰度部署的方案)
总感觉很简单 可就是很简单的问题就是一直曝405接口not allow
最终的问题解决了 原因:是因为 我后端个别接口在使用LocalDateTime 类型进行 json数据转换时 报错了 但是后端没有处理 也没有抛异常 这就导致我单独测试某一个接口是正常
而因为转换异常 导致后端的跨域访问配置失效了 继而 nginx里也没有对跨域的请求进行处理 就是下面这段代码 如果说后端配置了跨域配置且生效了 则nginx里就不用再配置了
因为我的数据转换异常了 所以导致后端跨域配置失效了 所以nginx就一直在代理的时候 曝405 not allow 异常
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 200;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
最终在所有
LocalDateTime 字段上都添加了注解
@JsonFormat(locale="zh", timezone="GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startmsgctime;
这里还要搭配上有自己的josn转换配置
@Component
public class FastJsonConvert {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
System.out.println("设置fastjson为springboot默认json");
FastJsonHttpMessageConverter fastConvert = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.WriteMapNullValue, // 是否输出值为null的字段,默认为false,我们将它打开
SerializerFeature.WriteNullListAsEmpty, // 将Collection类型字段的字段空值输出为[]
SerializerFeature.WriteNullStringAsEmpty, // 将字符串类型字段的空值输出为空字符串
SerializerFeature.WriteNullNumberAsZero, // 将数值类型字段的空值输出为0
SerializerFeature.WriteDateUseDateFormat,
SerializerFeature.DisableCircularReferenceDetect); // 禁用循环引用
//处理日期时间格式化问题
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
//处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastConvert.setSupportedMediaTypes(fastMediaTypes);
fastConvert.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters((HttpMessageConverter<?>) fastConvert);
}
}最后在贴上nginx的反向代理的关键配置
server {
#侦听80端口
listen 80;
#定义使用 www.nginx.cn访问
server_name localhost;
#定义服务器的默认网站根目录位置
#root html;
#设定本虚拟主机的访问日志
access_log logs/nginx.access.log main;
location / {
#程序根目录配置
root html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /xxapi {
# 后端接口请求转发
proxy_pass http://localhost:16101;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
凡所有相,皆是虚妄