0%

fetch + flask跨域请求带cookie

采用的web前后端分离的模式,flask做的后台接口,需要校验cookie,下面就react fetch的配置做个记录。

1.接口没要求做cookie的校验

fetch需要配置cors:

1
2
3
4
5
6
7
8
fetch('http://127.0.0.1:5000/interfaceList',{
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: par
})

服务端直接配置允许跨域就ok了:

1
2
3
4
5
6
7
# 狗跨域
def cors_response(res):
response = make_response(jsonify(res))
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'POST'
response.headers['Access-Control-Allow-Headers'] = "Referer,Accept,Origin,User-Agent"
return response

2.需要校验cookie

配置fetch模式:

1
2
3
4
5
6
7
8
9
fetch('http://127.0.0.1:5000/interfaceList',{
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: par,
credentials: "include"
})

上面的配置,浏览器会报错:

1
Failed to load http://127.0.0.1:5000/interfaceList: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:9090' is therefore not allowed access.

服务端需要配置:

1
2
3
4
5
6
7
8
# 狗跨域
def cors_response(res):
response = make_response(jsonify(res))
response.headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1:9090'
response.headers['Access-Control-Allow-Methods'] = 'POST'
response.headers['Access-Control-Allow-Headers'] = "Referer,Accept,Origin,User-Agent"
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response

优化建议

如果origin不确定可以从headers里去,再塞给response

1
2
3
4
5
6
7
8
9
10
11
origin = request.headers.get('origin')
.
.
.
def cors_response(res,origin):
response = make_response(jsonify(res))
response.headers['Access-Control-Allow-Origin'] = origin
response.headers['Access-Control-Allow-Methods'] = 'POST'
response.headers['Access-Control-Allow-Headers'] = "Referer,Accept,Origin,User-Agent"
response.headers['Access-Control-Allow-Credentials'] = 'true'
return response

3.webpack配置跨域

这是比较推荐的方式,不用改代码。
修改‘.webpackrc.js’,这样对应的‘/rest/xxx’就到ccc域名了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
proxy: {
'/rest': {
target: 'http://ccc.cccc.com',
changeOrigin: true
},
'/secure': {
target: 'http://xxx.xxxc.com',
changeOrigin: true
},
'/api': {
target: 'http://xxxxxx:8000',
changeOrigin: true,
},
},

当然这种只能在开发时调试使用,如果真的打包部署,还是要在nginx等转发服务器上做update stream跳转。