跨域的常见问题和解决方案
第一种
No 'Access-Control-Allow-Origin' header is present on the requested resource
The response had HTTP status code 404
出现这种情况的原因如下:
- 本次ajax请求是“非简单请求”,所以请求前会发送一次预检请求(OPTIONS)
- 服务器端后台接口没有允许OPTIONS请求,导致无法找到对应接口地址
解决方法
//node
//koa
const Koa = require('koa');
const app = new Koa();
const router = require('./router');
app.use(router.routes());
app.use(router.allowedMethods());
//java
//CorsFilter.java
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest)servletRequest;
String method = request.getMethod();
if(method.equalsIgnoreCase("OPTIONS")){ //处理OPTIONS请求
servletResponse.getOutputStream().write("Success".getBytes("utf-8"));
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
}
}
//web.xml
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>xxx.xxx.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第二种
No 'Access-Control-Allow-Origin' header is present on the requested resource
The response had HTTP status code 405
原因是接口不允许 会或者缺少GET,POST对应的接口暴露,比如 GET写成了POST,或者是其他安全策略阻止了访问
第三种
No 'Access-Control-Allow-Origin' header is present on the requested resource
status 200
原因是 头部匹配时出现不匹配现象
解决方法
//node
async (ctx, next) => {
ctx.set({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
});
ctx.type = 'application/json'
ctx.body = {code:0}
}
//nginx
server {
listen 80;
server_name www.chuchur.com;
location / {
proxy_pass http://www.chuchur.org; #反向代理
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.chuchur.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
//java 在Filter 里面加入
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
第四种
Request header field x-csrf-token is not allowed by Access-Control-Allow-Headers in preflight response.
原因是客户端头部信息('x-csrf-token')不被后端接收.两边同步下就可以了
第五种
The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
出现这个原因是 重复配置了跨域的头部信息导致的, 比如:
//node http://192.168.0.100:7001 node run in 7001
async (ctx, next) => {
ctx.set({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
});
ctx.type = 'application/json'
ctx.body = {code:0}
}
//nginx proxy to nginx 7001
server {
listen 80;
server_name www.chuchur.com;
location / {
proxy_pass http://192.168.0.100:7001; //转发到node的7001
add_header Access-Control-Allow-Origin *; //当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
//
当客户端通过nginx 上传图片的时候就会出现这个问题, node 和 nginx 同时配置了跨域的头部信息