enz*_*erg 6 post http cors http-options-method preflight
我的前端代码:
<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})
})
}
}
Run Code Online (Sandbox Code Playgroud)
和我的Express.js服务器代码:
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();
});
Run Code Online (Sandbox Code Playgroud)
当我提交表单时,我收到两个请求.其中一个是OPTIONS请求,另一个是POST请求,对它的响应是正确的: 在此处输入图像描述在此处输入图像描述在此处输入图像描述
如您所见,Express服务器在端口8000上运行,React开发服务器在端口3000上运行.localhost:3000正在请求localhost:8000/search,并且localhost:8000正在使用POST方法请求另一个源.但是,只有第二个请求才能正常运行.我不知道这是怎么发生的.当然,如果我使用查询字符串发出GET请求,那么事情是正常的.但我也想知道如何使用请求体进行POST提取.
这个OPTIONS请求是通过浏览器自动发送它自己,它会尝试之前,POST从您的代码的请求.它被称为CORS预检.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests有详细信息.
在您的特定情况下,它的要点是Content-Type: application/json您的代码添加的请求标头是触发浏览器执行该预检OPTIONS请求的内容.
这样特定的预检请求的目的是让浏览器向服务器请求,"你允许跨域POST有一个请求Content-Type头,其价值没有之一application/x-www-form-urlencoded,multipart/form-data或text/plain?"
并且为了使浏览器认为预检成功,服务器必须发回一个带有Access-Control-Allow-Headers响应头的响应,该响应头包含Content-Type在其值中.
所以我看到你已经有了res.header('Access-Control-Allow-Headers', 'Content-Type')当前的服务器代码http://localhost:8000/,如果你要以这种方式手动编码,这是正确的设置值.但我认为不起作用的原因是因为您没有明确处理OPTIONS请求的代码.
要解决此问题,您可以尝试安装npm cors包:
npm install cors
Run Code Online (Sandbox Code Playgroud)
......然后做这样的事情:
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');
});
Run Code Online (Sandbox Code Playgroud)
这将处理OPTIONS您的请求,同时还发回正确的标题和值.
| 归档时间: |
|
| 查看次数: |
6928 次 |
| 最近记录: |