在遇到前端跨域请求时,由于浏览器受同源策略的限制,如果不方便设置前端代理,那就要后端设置允许跨域,下面以常见语言或服务器环境为例来设置。
跨源资源共享(CORS):developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
php
// 服务器端相应数据类型
header('Content-Type: application/json;charset=utf-8');
// 或 header('Content-Type: text/html;charset=utf-8');
// *代表允许任何网址请求
header('Access-Control-Allow-Origin:*');
// 允许请求的类型
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE');
// 设置是否允许发送 cookies
header('Access-Control-Allow-Credentials: true');
// 设置允许自定义请求头的字段
header('Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with,Origin');
// 还如:header("access-control-allow-headers: Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With");
说明:
- 上面每项不是必须的,请根据实际需求来设定。
- 限定域名使用
header("Access-Control-Allow-Origin: www.xxx.xom");
- 如果设置后,
get
跨域请求正常,post
异常,可能是Access-Control-Allow-Headers
项问题,如没有包含Content-Type
等。或者POST
请求中对Content-Type
使用application/json
这个标头修改为application/x-www-form-urlencoded
试试。
Java
- 如果服务端是
Java
开发的,添加如下设置允许跨域即可,但是这样做是允许所有域名都可以访问,不够安全:response.setHeader("Access-Control-Allow-Origin","*");
- 为保证安全性,可以只添加部分域名允许访问,添加位置可以在下面三处任选一个。可以在过滤器的
filter
的dofilter()
方法种设置;可以在servlet
的get
或者post
方法里面设置;可以放在访问的jsp
页面第一行。 - 在此用第一种方法,注意
web.xml
配置过滤器(filter)。
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
// 将ServletResponse转换为HttpServletResponse
HttpServletResponse httpResponse = (HttpServletResponse) res;
// 如果不是80端口,需要将端口加上,如果是集群,则用Nginx的地址,同理不是80端口要加上端口
String [] allowDomain= {"http://www.baidu.com","http://127.0.0.1","http://127.0.0.1:8080"};
Set allowedOrigins= new HashSet(Arrays.asList(allowDomain));
String originHeader=((HttpServletRequest) req).getHeader("Origin");
if (allowedOrigins.contains(originHeader)){
httpResponse.setHeader("Access-Control-Allow-Origin", originHeader);
httpResponse.setContentType("application/json;charset=UTF-8");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
// 如果要把Cookie发到服务器,需要指定Access-Control-Allow-Credentials字段为true
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Expose-Headers", "*");
}
chain.doFilter(req, res);
}
NGINX
目前很多请求都不是直接暴露的,很多通过 nginx 做反向代理,因此可以使用 nginx 配置固定请求的 Access-Control-Allow-Origin,实现跨域访问。方式是在被请求的接口,配置 location 代理,添加 header 实现。
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers "x-requested-with,Authorization";
add_header Access-Control-Allow-Methods *;
Node
Express
const express = require("express");
const app = express();
//设置跨域访问
app.all("*",function(req,res,next){
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin","*");
//允许的header类型
res.header("Access-Control-Allow-Headers","content-type");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
if (req.method.toLowerCase() == 'options')
res.send(200); //让options尝试请求快速结束
else
next();
});
Koa2
参考:www.npmjs.com/package/koa2-cors
var Koa = require('koa');
var cors = require('koa2-cors');
// npm install --save koa2-cors
var app = new Koa();
app.use(cors({
origin: function(ctx) {
if (ctx.url === '/test') { // 禁止跨域请求/test
return false;
}
return '*';
// return ctx.header.origin;// 当*无法使用时,使用这句,同样允许所有跨域
// 单个跨域请求
// return 'http://localhost:8080';
// 允许多个跨域
// var allowCors = ['http://localhost:8080', 'http://localhost:8081'];
// return allowCors.indexOf(ctx.header.origin) > -1 ? ctx.header.origin : '';
},
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
maxAge: 5,
credentials: true,
allowMethods: ['GET', 'POST', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
}));
Python
Flask
1、使用 flask 内置的 after_request() 方法
app = Flask(__name__)
# 跨域支持
def after_request(resp):
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
app.after_request(after_request)
2、使用 flask_cors 模块
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
asp.net
设置 config 方式
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST,OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
asp
这个只有收藏意义了。
Response.AddHeader "Access-Control-Allow-Origin", "*"
Response.AddHeader "Access-Control-Allow-Credentials", "true"
Response.AddHeader "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"
Response.AddHeader "Access-Control-Allow-Headers", "Content-Type, Authorization, Accept,X-Requested-With"