JS跨域问题:response响应码200但response.ok=false或者是mode:no-cors出bug
用js实现一个前端向后端进行网络通信的代码时遇到的跨域问题,造成前端无法获取后院响应内容。
知识点:fetch中mode的参数选择“cors和no-cors”的区别
问题描述
提示:这里描述项目中遇到的问题:
最开始在js中用fetch实现的向后端发送数据的代码,mode模式为’cors’。
const resp = fetch('http://'+IP+':' + port + '/sendMessage', {
method: 'POST',
body: JSON.stringify(data),
mode: 'cors',
cache: 'no-store',
}).then(
response =>response.json())
.then(
data=>{
console.log('data',data.message);
}
).catch(error => console.error(error));
fetch的mode配置项有3个值,如下:
same-origin:该模式是不允许跨域的,它需要遵守同源策略,否则浏览器会返回一个error告知不能跨域;其对应的response type为basic。
cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求不需要后端额外的CORS支持;其对应的response type为cors。
no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;这也是fetch的特殊跨域请求方式;其对应的response type为opaque。
“禁止跨域”指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。最简单的说就是从当前域名的网站下不能请求非同源的地址所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域。
原因分析:
提示:这里填写问题的分析:
当直接使用mode:cors支持跨域请求时,由于后端没有配置跨域,会造成如下报错:
Access to fetch at 'IP' from origin 'chrome-extension://id' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
其实写的很清楚响应没有设置header,但是我直接就把mode改成no-cors了。之后no-cors响应为空,使用json()解析会出现Unexpexted end of input。
解决方案:
mode改成cors支持跨域
后端添加Access-Control-Allow-Origin的请求头
如果使用python的flask框架的话可以这么写:
#你的数据
json_str = json.dumps(data, ensure_ascii=False)
#创造一个response
resp = make_response(json_str)
#响应头设置
resp.headers["Content-Type"] = "application/json;chartset=UTF-8" # 设置响应头
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Methods'] = 'GET,POST,OPTIONS' # 如果有其它方法(delete,put等),断续添加
resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
这次bug出现的主要原因是没认真看报错,希望大家以我为戒,明明都写清楚了后端没设定响应头啊啊啊啊啊啊啊啊啊啊!!!