记一次跨域和nginx配置问题
问题描述
- 请求是跨域请求,从a.mycompony.com到b.mycompony.com;后端设置了如下参数,表示前端允许post和get方式跨域请求
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET");
response.setHeader("Access-Control-Allow-Headers", "Authentication,Content-Type");
- 同样的跨域请求,get方式的请求能够正常访问到上游服务器,post请求却不能,报403 forbidden request;
- 还有一个重要信息,这个post请求在以前是可以正常访问到后端的,并且前段没有改动过这部分代码
问题排查
- 请求方式不同,导致差异,说明问题出在后端服务器上游;
- 前端没有变动,且以前可以正常访问,说明问题出在代理服务器nginx上
- 查看nginx配置,发现类似如下代码
if($request_method != (POST|GET|HEAD)){
return 403;
}
关于跨域
- 跨域可分为简单请求和非简单请求
- 简单请求类似正常请求,只是在请求头信息和响应头加以区别;
- 非简单请求会将请求分为两次请求,第一次的请求为OPTION方式,用于预检是否支持第二次的请求方式、域名的访问请求,比如POST等;例如后端设置:
response.setHeader("Access-Control-Allow-Origin", "a.mycompony1.com");
response.setHeader("Access-Control-Allow-Methods", "POST,GET");
如果前端请求用PUT方式或者跨域域名为b.mycompony.com,后端返回200状态码,但是实际是不允许跨域的。错误以XHR对象的onError事件表现出来,需要前端用户手动处理。如果允许访问,则进行第二次类似简单请求的请求
OPTIONS /getListCORS HTTP/1.1
Origin: http://b.mycompony.com
Access-Control-Request-Method: PUT
总结:我们的403报错是因为nginx不支持OPTION请求方式的访问,删除访问限制后可正常进行
参考文档:
阮一峰的blo
MDN开发者文档