发出POST请求后,为什么会收到OPTIONS请求? [英] Why do I get an OPTIONS request after making a POST request?
问题描述
我的前端代码:
<form action="" onSubmit={this.search}>
<input type="search" ref={(input) => { this.searchInput = input; }}/>
<button type="submit">搜索</button>
</form>
// search method:
const baseUrl = 'http://localhost:8000/'; // where the Express server runs
search(e) {
e.preventDefault();
let keyword = this.searchInput.value;
if (keyword !== this.state.lastKeyword) {
this.setState({
lastKeyword: keyword
});
fetch(`${baseUrl}search`, {
method: 'POST',
// mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/json'
}),
// credentials: 'include',
body: JSON.stringify({keyword})
})
}
}
我的Express.js服务器代码:
And My Express.js server code:
app.all('*', (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
// res.header('Access-Control-Allow-Credentials', true);
res.header('Content-Type', 'application/json; charset=utf-8')
next();
});
提交表单时,我收到两个请求.其中一个是OPTIONS请求,另一个是POST请求,对它的响应是正确的:
When I submit the form, I get two requests. One of them is an OPTIONS request, and another one is an POST request and the response to it is right:
如您所见,Express服务器在端口8000上运行,而React开发服务器在端口3000上运行.localhost:3000
正在请求localhost:8000/search
,而localhost:8000
正在通过POST方法请求另一个来源.但是,只有第二个请求可以正常工作.我不知道这是怎么发生的.当然,如果我使用querystring发出GET请求,那是正常的.但我也想知道如何使用请求正文进行POST提取.
As you can see, the Express server runs on port 8000, and the React development server runs on port 3000. localhost:3000
is requesting localhost:8000/search
, and localhost:8000
is requesting another origin via using a POST method. However, only the second request works well. I don't know how this happen. Of course, If I make a GET request with querystring, things are normal. But I also want to know how to make a POST fetch with the request body.
推荐答案
该OPTIONS
请求由浏览器自行发送,然后再尝试从您的代码尝试POST
请求.这称为CORS手术前检查.
That OPTIONS
request is sent automatically by your browser on its own, before it tries the POST
request from your code. It’s called a CORS preflight.
https://developer.mozilla.org/en -US/docs/Web/HTTP/CORS#Preflighted_requests 包含详细信息.
在您的特定情况下,要点是代码添加的Content-Type: application/json
请求标头是触发浏览器执行该预检OPTIONS
请求的原因.
The gist of it in your specific case is that the Content-Type: application/json
request header that your code is adding is what triggers the browser to do that preflight OPTIONS
request.
因此,该特定的预检请求的目的是让浏览器询问服务器您是否允许跨域的POST
请求具有Content-Type
标头,而该标头的值不是multipart/form-data
或text/plain
?"
So the purpose of that particular preflight request is for the browser to ask the server, "Do you allow cross-origin POST
requests that have a Content-Type
header whose value isn’t one of application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
?"
And for the browser to consider the preflight successful, the server must send back a response with an Access-Control-Allow-Headers
response header that includes Content-Type
in its value.
因此,我看到您在http://localhost:8000/
的当前服务器代码中已经包含res.header('Access-Control-Allow-Headers', 'Content-Type')
,如果您要以这种方式手动对其进行编码,那么这是正确设置的值.但我认为无法正常运行的原因是,您还没有明确处理OPTIONS
请求的代码.
So I see that you’ve got res.header('Access-Control-Allow-Headers', 'Content-Type')
in your current server code on http://localhost:8000/
, and that’s the right value to set if you’re going to code it manually that way. But I think the reason that’s not working is because you don’t also have code that explicitly handles OPTIONS
requests.
要解决此问题,您可以尝试安装npm cors
软件包:
To fix that, you might try instead installing the npm cors
package:
npm install cors
…然后做这样的事情:
var express = require('express')
, cors = require('cors')
, app = express();
const corsOptions = {
origin: true,
credentials: true
}
app.options('*', cors(corsOptions)); // preflight OPTIONS; put before other routes
app.listen(80, function(){
console.log('CORS-enabled web server listening on port 80');
});
这将为您处理OPTIONS
请求,同时还发送回正确的标题和值.
That’ll handle the OPTIONS
request for you, while also sending back the right headers and values.
这篇关于发出POST请求后,为什么会收到OPTIONS请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!