最近在用react
+node.js
做项目的时候遇到一个问题:前端需要post
给服务器的内容为json
格式的(也就是content-type
为application/json
的格式),使用fetch()
来与服务器进行交互时,设置 headers
的中content-type
为application/json
,数据发送不到到服务器并报错如下:
我明明时候用的是post
方法!
然而试了很多种方法之后,在headers里添加mode:'no-cors'
(意为”不跨域“)后,能提交成功,但是查看request
的headers
发现content-type
自动变成了text-plain
,这并不是服务器期望接受到的数据格式。
后来我goooooooogle了一下,在stackoverflow上看到这样一段回答:
大概意思为:在'no-cors'
模式下,我们不能修改content-type
,而content-type
的值只能是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
。
如果不设置mode
,直接设置content-type
为application/json
,则fetch
会默认这是跨域模式(mode:'cors'
),在跨域POST之前,客户端会先发一条OPTIONS
请求来”探探路”,如果服务器允许,再继续POST
数据。对于这种OPTIONS
请求,需要在服务器配置允许接受OPTIONS
请求,我的配置如下:
if (ctx.request.method == "OPTIONS") {
ctx.response.status = 200
}
我这样写就是直接允许了所有的OPTIONS
请求,也可以按照需求来判断OPTIONS
请求中更详细的信息。
当然,如果你的项目确实涉及到跨域问题,除了判断OPTIONS
方法的请求之外,还需要配置一下请求头,我的node.js
项目中的配置如下(使用的是KOA2框架):
app.use(async(ctx, next) => {
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set("Access-Control-Allow-Credentials", true);
ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
ctx.set("X-Powered-By", ' 3.2.1');
ctx.set("Content-Type", "application/json;charset=utf-8");
if (ctx.request.method == "OPTIONS") {
ctx.response.status = 200
}
}
await next();
});
这样,前端就不需要再做跨域处理了。
新手上路,理解有误的请大家指正~
=============2017.6.16更新==================
nodejs中跨域header配置中的header字段,一定要跟fetch里设置的header字段一致,比如:
在nodejs中配置头文件:
ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
那么,在fetch中配置content-type
要写得与上述代码中的一致。nodejs中写的是content-type
,fetch中就写content-type
,写成contentType
就不可以,会被拒绝。