Node.js 为什么浏览器发送选项请求,即使我的前端代码只是发出POST请求?
我的前端代码:Node.js 为什么浏览器发送选项请求,即使我的前端代码只是发出POST请求?,node.js,express,cors,preflight,http-options-method,Node.js,Express,Cors,Preflight,Http Options Method,我的前端代码: <form action="" onSubmit={this.search}> <input type="search" ref={(input) => { this.searchInput = input; }}/> <button type="submit">搜索</button> </form> // search method: const baseUrl = 'http://localhost:
<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})
})
}
}
当我提交表格时,我收到两个请求。其中一个是选项请求,另一个是POST请求,响应正确:
如您所见,Express服务器在端口8000上运行,React开发服务器在端口3000上运行
localhost:3000
正在请求localhost:8000/search
,而localhost:8000
正在使用POST方法请求其他来源。然而,只有第二个请求工作得很好。我不知道这是怎么发生的。当然,如果我使用querystring发出GET请求,一切正常。但是我还想知道如何使用请求正文进行POST获取。在您的浏览器尝试从您的代码发出POST
请求之前,您的浏览器会自动发送选项
请求。这叫做CORS飞行前准备
他有详细资料
在您的具体案例中,它的要点是您的代码添加的内容类型:application/json
请求头触发浏览器执行飞行前选项
请求
因此,该特定的飞行前请求的目的是让浏览器询问服务器,“是否允许跨源POST
请求具有内容类型
标题,其值不是应用程序/x-www-form-urlencoded
、多部分/表单数据
或文本/普通
?”
<> P>和浏览器考虑飞行前成功,服务器必须返回一个响应头,其中包含了代码>内容类型< /代码>的值。
因此,我看到您在上的当前服务器代码中有res.header('Access-Control-Allow-Headers','Content-Type')
http://localhost:8000/
,如果要以这种方式手动编写代码,那么这就是要设置的正确值。但我认为这不起作用的原因是,您没有明确处理选项
请求的代码
要解决此问题,您可以尝试安装npmcors
软件包:
npm install cors
…然后像这样做:
var express=require('express'))
,cors=require('cors'))
,app=express();
常数常数={
来源:对,
凭据:正确
}
应用程序选项(“*”,cors(corsOptions));//飞行前选择;优先于其他路线
app.listen(80,函数(){
log('CORS-enabledwebserver监听端口80');
});
这将为您处理
选项
请求,同时返回正确的标题和值 我最近遇到了类似的问题,使用FormData发送我的请求负载,您不需要发送自定义头。FormData对象负责为您提供身份验证凭据,但它使用SSL,并且只能使用https,而https不是由localhost提供的,因为localhost使用http协议。
有关如何在express应用程序中安装和使用FormData的详细信息,请查看FormData,但FormData可在主要浏览器中随时使用。
下面是一个简单的代码示例
npm安装--保存表单数据
`
`谢谢!我知道我的
fetch()
函数和设置响应头的代码都不好,我已经试过很多次了(也许你可以看到很多代码正在被注释)。您能告诉我如何使用fetch
并正确设置响应标题吗?您的fetch
调用很好。但是您需要在http://localhost:8000/
请求发送到的服务器。查看我的最新答案。这将导致服务器正确处理飞行前选项请求,并将必要的CORS头发回。如果不这样做,您的浏览器将阻止前端JavaScript代码发送该POST
请求,只要您将内容类型:application/json
请求头添加到请求中即可。在我的情况下,访问控制允许原始
,Access Control Allow header
和Access Control Allow Method
是不够的,我必须添加Access Control Max Age:86400
,才能让它工作。我猜浏览器需要“访问权限”有效期的信息“您不需要发送自定义标题”-是的,您需要。“FormData对象为您处理身份验证凭据”-不,它不需要。“只能使用https,而https不是由本地主机提供的,因为本地主机使用http协议”-没有任何东西阻止您安装支持HTTPS并在本地主机上侦听的服务器…FormData与HTTP配合使用也很好。“查看form data npm文档,了解如何在您的express app中安装和使用它的详细信息”-他们正在从浏览器发出请求,因此这没有帮助。
npm install cors
var FormData = require('form-data');
var http = require('http');
var form = new FormData();
http.request('http://nodejs.org/images/logo.png', function(response) {
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_logo', response);
});