为什么我的 JavaScript 代码会收到“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误,而 Postman 却不会?
Mod note : This question is about why
XMLHttpRequest
/fetch
/etc. on the browser are subject to the Same Access Policy restrictions (you get errors mentioning CORB or CORS) while Postman is not. This question is not about how to fix a "No 'Access-Control-Allow-Origin'..." error. It's about why they happen.
Please stop posting :
- CORS configurations for every language/framework under the sun. Instead find your relevant language/framework's question .
- 3rd party services that allow a request to circumvent CORS
- Command line options for turning off CORS for various browsers
我正在尝试使用 JavaScript 通过连接到 RESTful API 内置 Flask 进行授权。但是,当我发出请求时,出现了以下错误:
XMLHttpRequest cannot load http://myApiUrl/login.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access.
我知道 API 或远程资源必须设置标头,但是为什么当我通过 Chrome 扩展程序 Postman 发出请求时,它会起作用呢?
这是请求代码:
$.ajax({
type: 'POST',
dataType: 'text',
url: api,
username: 'user',
password: 'pass',
crossDomain: true,
xhrFields: {
withCredentials: true,
},
})
.done(function (data) {
console.log('done');
})
.fail(function (xhr, textStatus, errorThrown) {
alert(xhr.responseText);
alert(textStatus);
});
如果我理解正确的话,您正在向与页面所在域不同的域执行 XMLHttpRequest 。因此,浏览器会阻止它,因为出于安全原因,它通常允许来自同一来源的请求。当您想要执行跨域请求时,您需要做一些不同的事情。
当您使用 Postman 时,它们不受此策略的限制。引自 Cross-Origin XMLHttpRequest :
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
WARNING: Using
Access-Control-Allow-Origin: *
can make your API/website vulnerable to cross-site request forgery (CSRF) attacks. Make certain you understand the risks before using this code.
如果您使用 PHP ,则解决起来非常简单。只需在处理请求的 PHP 页面开头添加以下脚本:
<?php header('Access-Control-Allow-Origin: *'); ?>
如果您使用的是
Node-red
,则必须在
node-red/settings.js
文件中取消注释以下行,以允许
CORS
:
// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
origin: "*",
methods: "GET,PUT,POST,DELETE"
},
如果您使用的是
Flask
,与问题相同;您必须首先安装
flask-cors
pip install -U flask-cors
然后在您的应用程序中包含 Flask cors 包。
from flask_cors import CORS
一个简单的应用程序将如下所示:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
有关更多详细信息,您可以查看 Flask 文档 。
因为
$.ajax({type: "POST"
- 调用
OPTIONS
$.post(
- 调用
POST
两者不同。 Postman 正确调用“POST”,但当我们调用它时,它将是“OPTIONS”。
对于 C# Web 服务 - Web API
请在您的 web.config 文件的 <system.webServer> 标记下添加以下代码。这将工作:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
请确保您在 Ajax 调用中没有犯任何错误。
jQuery
$.ajax({
url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST", /* or type:"GET" or type:"PUT" */
dataType: "json",
data: {
},
success: function (result) {
console.log(result);
},
error: function () {
console.log("error");
}
});
注意: 如果您要从 第三方网站 下载内容,那么 这将对您没有帮助 。您可以尝试以下代码,但不能尝试 JavaScript。
System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");