
[英]Why does my JavaScript code get a “No 'Access-Control-Allow-Origin' header is present on the requested resource”
[英]Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?
Mod note : 这个问题是关于为什么
XMLHttpRequest
/fetch
/etc. 在浏览器上受相同访问策略限制(您会收到提及 CORB 或 CORS 的错误),而 Postman 则不受。 这个问题不是关于如何修复“没有'Access-Control-Allow-Origin'...”错误。 这是关于它们发生的原因。
请停止发帖:
- CORS 每种语言/框架的配置。 而是找到你相关的语言/框架的问题。
- 允许绕过 CORS 请求的第三方服务
- 为各种浏览器关闭 CORS 的命令行选项
我正在尝试通过连接到内置的Flask的RESTful API使用JavaScript进行授权。 但是,当我发出请求时,出现以下错误:
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 或远程资源必须设置 header,但为什么当我通过 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 。 因此浏览器会阻止它,因为出于安全原因,它通常允许同一来源的请求。 当您想要进行跨域请求时,您需要做一些不同的事情。 有关如何实现这一点的教程是使用 CORS 。
当您使用 Postman 时,它们不受此政策的限制。 引用自跨域 XMLHttpRequest :
常规网页可以使用 XMLHttpRequest 对象从远程服务器发送和接收数据,但它们受到同源策略的限制。 扩展并没有那么有限。 扩展程序可以与其源之外的远程服务器通信,只要它首先请求跨域权限。
这不是针对生产的解决方案,也不是必须将应用程序显示给客户端的解决方案,这仅在UI和后端开发位于不同服务器上且在生产中它们实际上位于同一服务器上时才有用。 例如:在为任何应用程序开发UI时,如果需要在本地对其进行测试以将其指向后端服务器,那么在这种情况下,这是完美的解决方案。 对于生产修复,必须将CORS标头添加到后端服务器,以允许跨源访问。
简单的方法是只在Google chrome中添加扩展名,以允许使用CORS进行访问。
只要您想允许不访问任何“ access-control-allow-origin”头请求,就启用此扩展。
要么
在Windows中,将此命令粘贴到运行窗口中
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
这将打开一个新的Chrome浏览器,该浏览器不允许访问“ access-control-allow-origin”标头请求。
警告:使用
Access-Control-Allow-Origin: *
会使您的 API/网站容易受到跨站请求伪造(CSRF) 攻击。 在使用此代码之前,请确保您了解风险。
如果您使用的是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 文档。
我希望有人在很早以前就与我共享了此站点http://cors.io/ ,与构建和依赖我自己的代理相比,它将节省大量时间。 但是,在进入生产阶段时,拥有自己的代理服务器是最好的选择,因为您仍然可以控制数据的各个方面。
一切你需要的:
https://cors.io/?http://HTTP_YOUR_LINK_HERE
因为
$.ajax({type: "POST" - 调用选项
$.post( - 调用POST
两者是不同的。 邮递员正确地调用“POST”,但当我们调用它时,它将是“OPTIONS”。
对于 C# Web 服务 - Web API
请在 <system.webServer> 标签下的web.config文件中添加以下代码。 这将起作用:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
请确保您在 Ajax 调用中没有犯任何错误
$.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");
如果您使用的是Node.js ,请尝试:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
详细信息: ExpressJS上的CORS
使用Ajax存在跨域问题。 您必须确定要在没有www.
的同一http://
路径上访问文件www.
(或从http://www.
访问并发布到包含www.
的相同路径),当通过www.
访问时浏览器将其视为另一个域www.
路径,以便您查看问题出在哪里。 您正在发布到另一个域,并且由于起源问题,浏览器阻止了流量。
如果API不在您所请求的同一主机上,则该流将被阻止,您将需要寻找另一种与API通信的方法。
在以下作为 API 的调查中,我使用http://example.com而不是您的问题中的 http://myApiUrl/login,因为这是第一个工作。 我假设您的页面位于http://my-site.local:8088上。
注意:API 和您的页面具有不同的域!
您看到不同结果的原因是 Postman:
Host=example.com
(您的 API)Origin
这类似于站点和 API 具有相同域时浏览器发送请求的方式(浏览器还设置了标头项Referer=http://my-site.local:8088
,但是我在 Postman 中看不到) . 当没有设置Origin
标头时,通常服务器默认允许此类请求。
这是 Postman 发送请求的标准方式。 但是当您的站点和 API 具有不同的域时,浏览器会发送不同的请求,然后发生CORS并且浏览器会自动:
Host=example.com
(你的作为 API)Origin=http://my-site.local:8088
(您的站点) (标头Referer
与Origin
具有相同的值)。 现在在 Chrome 的控制台和网络选项卡中,您将看到:
当你有Host != Origin
时,这是 CORS,当服务器检测到这样的请求时,它通常会默认阻止它。
当您从本地目录打开 HTML 内容并发送请求时,将设置Origin=null
。 同样的情况是当您在<iframe>
中发送请求时,就像在下面的代码片段中一样(但这里根本没有设置Host
标头)- 通常,HTML 规范在任何地方都说不透明的来源,您可以将其转换为Origin=null
。 您可以在此处找到有关此的更多信息。
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
如果你不使用简单的 CORS 请求,通常浏览器会在发送主请求之前自动发送一个 OPTIONS 请求 - 更多信息在这里。 下面的片段显示了它:
fetch('http://example.com/api', { method: 'POST', headers: { 'Content-Type': 'application/json'} });
Look in chrome-console -> network tab to 'api' request. This is the OPTIONS request (the server does not allow sending a POST request)
您可以更改服务器的配置以允许 CORS 请求。
这是一个在 nginx(nginx.conf 文件)上打开 CORS的示例配置 - 为 nginx 设置always/"$http_origin"
和为 Apache 设置"*"
时要非常小心 - 这将取消阻止来自任何域的 CORS(在生产中而不是星星使用你的具体页面地址,它消耗你的 api)
location ~ ^/index\.php(/|$) { ... add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'true' always; if ($request_method = OPTIONS) { add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above) add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin'; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain charset=UTF-8'; return 204; } }
这是在 Apache 上打开 CORS的示例配置(.htaccess 文件)
# ------------------------------------------------------------------------------ # | Cross-domain Ajax requests | # ------------------------------------------------------------------------------ # Enable cross-origin Ajax requests. # http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity # http://enable-cors.org/ # <IfModule mod_headers.c> # Header set Access-Control-Allow-Origin "*" # </IfModule> # Header set Header set Access-Control-Allow-Origin "*" # Header always set Access-Control-Allow-Credentials "true" Access-Control-Allow-Origin "http://your-page.com:80" Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
应用 CORS 限制是由服务器定义并由浏览器实现的安全功能。
浏览器查看服务器的 CORS 策略并尊重它。
但是,Postman 工具并不关心服务器的 CORS 策略。
这就是为什么 CORS 错误出现在浏览器中,而不是 Postman 中的原因。
您得到的错误是由于 CORS 标准造成的,该标准对 JavaScript 如何执行 ajax 请求设置了一些限制。
CORS 标准是在浏览器中实现的客户端标准。 因此,阻止调用完成并生成错误消息的是浏览器,而不是服务器。
Postman 没有实现 CORS 限制,这就是为什么在从 Postman 发出相同调用时看不到相同错误的原因。
为什么Postman 不实施 CORS? CORS 定义了与发起请求的页面的来源(URL 域)相关的限制。 但在 Postman 中,请求并非来自具有 URL 的页面,因此 CORS 不适用。
如果您想在 javascript 中使用 fetch API 或 XMLHttpRequest 获取内容时绕过该限制,您可以使用代理服务器,以便它将标头Access-Control-Allow-Origin
为*
。
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.get('/fetch', (req, res) => {
request(
{ url: req.query.url },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).send('error');
}
res.send(body);
}
)
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));
以上是可以充当代理服务器的示例代码(需要节点 Js)。 例如:如果我想正常获取https://www.google.com
会抛出 CORS 错误,但现在由于请求是通过本地托管在端口 3000 的代理服务器发送的,代理服务器添加了Access-Control-Allow-Origin
响应中的Access-Control-Allow-Origin
标头,不会有任何问题。
向 http://localhost:3000/fetch?url= Your URL here
发送 GET 请求,而不是直接将请求发送到您要获取的 URl。
Your URL here
的 URL 代表您希望获取的 URL,例如: https://www.google.com
: https://www.google.com
如果您不想:
并且您确定服务器随后启用了CORS(在此处测试CORS: http : //www.test-cors.org/ )
然后,您需要在请求中传递origin参数。 该来源必须与您的浏览器发送的与您的请求匹配的来源。
您可以在这里查看其运行情况: http : //www.wikinomad.com/app/detail/Campgrounds/3591
编辑功能将GET&POST请求发送到另一个域以获取数据。 我设置了可以解决问题的origin参数。 后端是mediaWiki引擎。
tldr:在您的调用中添加“ origin”参数,该参数必须是浏览器发送的Origin参数(您不能欺骗origin参数)
当我使用AngularJS访问我的API时遇到了这个问题。 相同的请求在SoapUI 5.0和ColdFusion中起作用。 我的GET方法已经具有Access-Control-Allow-Origin标头。
我发现AngularJS发出了“试用” OPTIONS请求 。 默认情况下,ColdFusion会生成OPTIONS方法,但是这些头并不多,特别是这些头。 生成该错误是为了响应该OPTIONS调用,而不是我对GET的有意调用。 将下面的OPTIONS方法添加到我的API后,问题已解决。
<cffunction name="optionsMethod" access="remote" output="false" returntype="any" httpmethod="OPTIONS" description="Method to respond to AngularJS trial call">
<cfheader name="Access-Control-Allow-Headers" value="Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin">
<cfheader name="Access-Control-Allow-Methods" value="GET,OPTIONS">
<cfheader name="Access-Control-Allow-Origin" value="*">
<cfheader name="Access-Control-Max-Age" value="360">
</cffunction>
根据shruti的回答 ,我创建了带有所需参数的Chrome浏览器快捷方式:
https://github.com/Rob--W/cors-anywhere/提供(Node.js)代码,您可以使用它们来设置和运行自己的CORS代理。 它得到了积极维护,并提供了许多功能来控制代理行为,而不仅仅是基本发送正确的Access-Control-*
响应头。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS包含详细信息,以解释浏览器如何处理客户端Web应用程序从JavaScript发出的跨域请求以及必须配置的标头如果可以,将请求发送到服务器。
如果您需要向其发出请求并获得响应的网站没有返回Access-Control-Allow-Origin
响应标头,则浏览器始终会阻止您的客户端直接向其提出的跨域请求侧JavaScript代码正常工作。 因此,如果该网站是不是一个可以控制,并且可以配置,只有这样才能在这种情况下,工作的事情是进行代理请求,无论是通过自己的代理服务器运行自己或通过一个开放的代理行为。
如此处其他评论所述,有充分的理由不信任您的请求的开放代理。 就是说,如果您知道自己在做什么,并且决定一个开放代理可以满足您的需求,则https://cors-anywhere.herokuapp.com/是可靠可用,主动维护并运行该代理实例的代理。 https://github.com/Rob--W/cors-anywhere/代码。
就像这里提到的其他开放代理(其中至少有一些似乎不再可用)一样,它的工作方式是与其让客户代码直接将请求发送到例如http://foo.com
您将其发送到https://cors-anywhere.herokuapp.com/http://foo.com
,并且代理将必要的Access-Control-*
标头添加到浏览器看到的响应中。
您正在向不同的域发出XMLHttpRequest ,例如:
some-domain.com
some-different-domain.com
域名的这种差异触发了称为SOP (同源策略)的CORS (跨域资源共享)策略,该策略强制在Ajax 、XMLHttpRequest 和其他 HTTP 请求中使用相同的域(因此是Origin )。
为什么当我通过 Chrome 扩展 Postman 发出请求时它会起作用?
客户端(大多数浏览器和开发工具)可以选择强制执行同源策略。
大多数浏览器执行同源策略以防止与CSRF (跨站点请求伪造)攻击相关的问题。
Postman作为开发工具选择不强制执行 SOP,而某些浏览器强制执行,这就是为什么您可以通过 Postman 发送您无法使用浏览器通过 JS 通过 XMLHttpRequest 发送的请求。
当从服务器请求响应时,我具有以下配置,导致相同的错误。
服务器端: SparkJava- >提供REST-API
客户端: ExtJs6- >提供浏览器渲染
在服务器端,我必须将其添加到响应中:
Spark.get("/someRestCallToSpark", (req, res) -> {
res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working
return "some text";
});
在客户端,我必须将此添加到请求中:
Ext.Ajax.request({
url: "http://localhost:4567/someRestCallToSpark",
useDefaultXhrHeader: false, //important, otherwise its not working
success: function(response, opts) {console.log("success")},
failure: function(response, opts) {console.log("failure")}
});
您可以使用YQL通过Yahoo的服务器代理请求,从而绕过该问题。 只是几行代码:
var yql_url = 'https://query.yahooapis.com/v1/public/yql';
var url = 'your api url';
$.ajax({
'url': yql_url,
'data': {
'q': 'SELECT * FROM json WHERE url="'+url+'"',
'format': 'json',
'jsonCompat': 'new',
},
'dataType': 'jsonp',
'success': function(response) {
console.log(response);
},
});
这是带有说明的链接: https : //vverma.net/fetch-any-json-using-jsonp-and-yql.html
如果您使用的是Entity Framework ,即使您启用了CORS
,似乎有时也会引发此错误。 我发现错误是由于缺少查询的最终确定而发生的。 我希望这可以帮助处于相同情况的其他人。
以下代码可以抛出XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.
XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.
错误:
using (DBContext db = new DBContext())
{
return db.Customers.Select(x => new
{
Name = x.Name,
CustomerId = x.CustomerId,
});
}
要解决此问题,需要在查询末尾完成诸如.ToList()
或.FirstOrDefault()
类的终结调用,如下所示:
using (DBContext db = new DBContext())
{
return db.Customers.Select(x => new
{
Name = x.Name,
CustomerId = x.CustomerId,
}).ToList();
}
以我为例,我使用的是JEE7 JAX-RS应用程序,以下技巧对我来说非常有效:
@GET
@Path("{id}")
public Response getEventData(@PathParam("id") String id) throws FileNotFoundException {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/eventdata/" + id + ".json");
JsonReader jsonReader = Json.createReader(inputStream);
return Response.ok(jsonReader.readObject()).header("Access-Control-Allow-Origin", "*").build();
}
我可以使用htaccess成功解决(以字体为例),但很明显,OP要求的差别不大。 但是您可以使用FileMatch模式并添加任何扩展名,以免出现cros错误。
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
如果您的服务器是Springboot应用程序,那么请在顶部的rest控制器中添加此注释- @CrossOrigin
现在应该可以工作了。 谢谢
如果您想在后端(在Flask中)而不是在前端上修复它,我将完全推荐Flask CORS Python软件包。 烧瓶CORS
在app.py中仅需一行即可自动插入标准,允许任何原始标头或根据需要对其进行自定义。
热门问题-如果您已读完本文但没有其他帮助,则要看的另一件事。 如果您拥有Akamai,Limelight或类似的CDN,则可能要检查具有资源URI的缓存键。 如果它不包括Origin头值,则可能是从另一个Origin请求时返回缓存的响应。 我们只花了半天时间调试它。 CDN配置已更新为仅包含属于我们的几个选定域的Origin值,而将所有其他域都设置为null。 这似乎可行,并且允许来自我们已知域的浏览器查看我们的资源。 当然,所有其他答案都是到达这里的先决条件,但如果CDN是浏览器的第一跳,则需要进行检查。
在我们的案例中,我们可以看到一些请求发送到我们的服务,但几乎没有网站发送的请求量。 这将我们引向了CDN。 我们可以回过头来查看原始请求是从直接请求提供的,而不是浏览器AJAX调用的一部分,并且响应标头Access-Control-Allow-Origin不包括在内。 显然,CDN缓存了该值。 Akamai CDN配置进行了调整,以考虑将Origin请求标头值作为匹配的一部分,这似乎使它对我们有用。
如果您从浏览器中收到此错误消息:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access
当您尝试对无法控制的远程服务器发出Ajax POST / GET请求时,请忽略以下简单解决方法:
<?php header('Access-Control-Allow-Origin: *'); ?>
您确实需要,特别是如果您仅使用JavaScript来执行Ajax请求,则需要一个内部代理来接受您的查询并将其发送到远程服务器。
首先,在您的JavaScript代码中,对您自己的服务器进行Ajax调用,例如:
$.ajax({
url: yourserver.com/controller/proxy.php,
async: false,
type: "POST",
dataType: "json",
data: data,
success: function (result) {
JSON.parse(result);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr);
}
});
然后,创建一个名为proxy.php的简单PHP文件,以包装POST数据并将其作为参数附加到远程URL服务器。 我举一个例子,说明如何使用Expedia Hotel搜索API绕过此问题:
if (isset($_POST)) {
$apiKey = $_POST['apiKey'];
$cid = $_POST['cid'];
$minorRev = 99;
$url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;
echo json_encode(file_get_contents($url));
}
通过做:
echo json_encode(file_get_contents($url));
您只是在执行相同的查询,但是在服务器端,此后它应该可以正常工作。
对于GoLang API:
首先,您可以看一下MDN CORS文档以了解什么是CORS。 据我所知,CORS是关于是否允许请求源访问服务器资源的。
您可以通过在“服务器响应” Header
中设置Access-Control-Allow-Origin
来限制哪个请求源可以访问服务器。
例如,在“服务器响应”中设置以下标头意味着仅从http://foo.example
发送的请求可以访问您的服务器:
Access-Control-Allow-Origin: http://foo.example
以及以下允许来自任何来源(或域)的请求:
Access-Control-Allow-Origin: *
正如我在错误消息中所知, requested resource
表示服务器的资源,因此requested resource
No 'Access-Control-Allow-Origin' header is present on the requested resource.
表示您没有在服务器响应中设置Access-Control-Allow-Origin
标头,或者您设置了该类,但请求的来源不在Access-Control-Allow-Origin
因此不允许访问请求:
所请求的资源上没有“ Access-Control-Allow-Origin”标头。 因此,不允许访问原始“空”。
在GoLang中,我使用gorilla/mux
软件包在localhost:9091
处构建API服务器,并且通过在响应标头中添加"Access-Control-Allow-Origin", "*"
来允许CORS:
func main() { // API Server Code
router := mux.NewRouter()
// API route is /people,
//Methods("GET", "OPTIONS") means it support GET, OPTIONS
router.HandleFunc("/people", GetPeople).Methods("GET", "OPTIONS")
log.Fatal(http.ListenAndServe(":9091", router))
}
// Method of '/people' route
func GetPeople(w http.ResponseWriter, r *http.Request) {
// Allow CORS by setting * in sever response
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
json.NewEncoder(w).Encode("OKOK")
}
而且我在客户端中使用JavaScript,在localhost:9092
,Chrome发出的请求可以从Server localhost:9091
成功获取“ OKOK”。
function GetPeople() {
try {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "http://localhost:9091/people", false);
xhttp.setRequestHeader("Content-type", "text/html");
xhttp.send();
var response = JSON.parse(xhttp.response);
alert(xhttp.response);
}
catch (error) {
alert(error.message);
}
}
此外,您可以通过Fiddler
类的工具检查请求/响应标头。
这些答案大多数都告诉用户如何将CORS标头添加到他们控制的服务器中。
但是,如果您需要不受网页控制的服务器中的数据,一种解决方案是在页面上创建脚本标签,将src属性设置为没有CORS标头的API端点,然后加载该数据到页面上:
window.handleData = function(data) {
console.log(data)
};
var script = document.createElement('script');
script.setAttribute('src','https://some.api/without/cors/headers.com&callback=handleData');
document.body.appendChild(script);
在JSONP请求中,您应该捕获“ jsonpCallback”并将其发送回:
$.ajax({
url: lnk,
type: 'GET',
crossDomain: true,
dataType: 'jsonp',
success: function (ip) { console.log(ip.ip); },
error: function (err) { console.log(err) }
});
在后端(如果您使用PHP作为后端):
echo $_GET['callback'].'({"ip":"192.168.1.1"})';
在这种情况下,后端响应类似于:
jQuery331009526199802841284_1533646326884({“ ip”:“ 192.168.1.1”})
但是您可以在前端手动设置“ jsonpCallback”,并在后端捕获它:
$.ajax({
url: lnk,
type: 'GET',
crossDomain: true,
dataType: 'jsonp',
jsonpCallback: 'get_ip',
success: function (ip) { console.log(ip.ip); },
error: function (err) { console.log(err) }
});
在这种情况下,后端响应类似于:
get_ip({“ ip”:“ 192.168.1.1”})
仅针对 .NET Core Web API 项目,添加以下更改:
ConfigureServices()
方法中的services.AddMvc()
行之后添加以下代码:services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
Configure()
方法中的app.UseMvc()
行之后添加以下代码:app.UseCors(options => options.AllowAnyOrigin());
[EnableCors("AllowOrigin")]
用于浏览器测试目的:Windows - 运行:
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
从JavaScript到我的php API,这在我身上经常发生,原因之一。 我忘了放<?php header('Access-Control-Allow-Origin: *'); ?
<?php header('Access-Control-Allow-Origin: *'); ?
是一个。 这对于跨子域访问很有帮助。 另一个原因是因为在jQuery ajax请求中我指定了特定的dataType并返回了不同的dataType,所以它引发了错误。
此错误的最后也是最主要的原因是您请求的页面上存在解析错误。 如果您在浏览器中击中该页面URL的可能性超过您可能会看到的解析错误,并且您将获得一个行号来解决该问题。
我希望这可以帮助别人。 每次调试都花了我一段时间,我希望我能核对一下清单。
如果您的网关超时太短并且您正在访问的资源的处理时间比超时时间长,您也可能会收到此错误。 这可能是复杂的数据库查询等的情况。因此,上面的错误代码可以掩盖这个问题。 只需检查错误代码是否为 504 而不是 404,如上面的 Kamils 回答或其他内容。 如果是 504,那么增加网关超时可能会解决问题。
在我的情况下,可以通过在 IE 浏览器中禁用同源策略 (CORS) 来消除 CORS 错误,请参阅如何禁用同源策略 Internet Explorer 。 执行此操作后,日志中出现纯 504 错误。
CORS适合您。
CORS是“跨源资源共享”,是一种发送跨域请求的方式。 现在XMLHttpRequest2和Fetch API都支持CORS。
但是它有其局限性。 服务器需要明确声明Access-Control-Allow-Origin ,并且不能将其设置为“ *”。
而且,如果您希望任何来源都可以向您发送请求,则需要JSONP(还需要设置Access-Control-Allow-Origin ,但可以为'*')。
对于很多请求方式,如果您不知道要选择什么,我认为您需要一个功能齐全的组件来做到这一点。 让我介绍一个简单的组件咔嗒
如果您使用的是现代浏览器(> Internet Explorer9,Chrome,Firefox,Edge等),则强烈建议您使用简单但美观的组件https://github.com/Joker-Jelly/catta 。 它没有依赖关系,小于3 KB,并且以相同的简陋语法和选项支持Fetch,Ajax和JSONP。
catta('./data/simple.json').then(function (res) {
console.log(res);
});
它还支持所有方式导入项目,例如ES6模块,CommonJS甚至HTML中的<script>
。
我在Angular中$http.get
这个错误。 我需要改用$http.jsonp
。
在我的网站(基于.NET)上,我刚刚添加了以下内容:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
非常感谢这部影片。
为了完整起见, Apache允许cors:
Header set Access-Control-Allow-Origin "http://www.allowonlyfromthisurl.com"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header set Access-Control-Max-Age "1000"
Header set Access-Control-Allow-Headers "x-requested-with, Content-Type, Accept-Encoding, Accept-Language, Cookie, Referer"
重新发布我的答案,版主删除了。 正如我所指出的,OP 的确切错误已由此修复。 在删除此答案之前,至少有 7 人同意这是一个有效的解决方案。
主持人:请考虑可能帮助一个人解决由外部原因引起的问题的价值。 javascript 消息在调试这个特定问题时仍然几乎没有用。 此线程仍然是 OP 确切错误消息的顶级搜索结果。
删除的答案如下:
流行的问题——如果你读到这里并且没有其他任何帮助,那么要考虑的另一件事。 如果您有诸如 Akamai、Limelight 或类似的 CDN,您可能需要检查您拥有的缓存密钥以获取资源的 URI。 如果它不包含 Origin 标头值,您可能会返回从另一个 Origin 请求时缓存的响应。 我们只花了半天时间调试这个。 CDN 配置已更新为仅包含我们的几个选定域的 Origin 值,并将其设置为所有其他域的 null。 这似乎有效并允许来自我们已知域的浏览器查看我们的资源。 当然,所有其他答案都是到达这里的先决条件,但如果 CDN 是您浏览器的第一跳,则需要查看此内容。
在我们的例子中,我们可以看到一些请求发送到我们的服务,但没有接近站点发送的数量。 这将我们引向了 CDN。 我们能够返回并看到原始请求是从直接请求中提供的,而不是浏览器 AJAX 调用的一部分,并且响应标头 Access-Control-Allow-Origin 未包含在内。 显然 CDN 缓存了这个值。 Akamai CDN 配置调整以将 Origin 请求标头值视为匹配的一部分似乎使其对我们有用。
要解决此问题,请在后端使用的doGet()
或doPost()
函数中编写这行代码
response.setHeader("Access-Control-Allow-Origin", "*");
而不是在网站或正在访问网站的 api url 端点中键入"*"
。
您的 IP 未列入白名单,因此您收到此错误。 要求后端人员将您正在访问的服务的 IP 列入白名单https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
“您可以做出的最快修复是安装moesif CORS扩展: https ://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc/related?hl=en-US
安装后,在浏览器中单击它以激活扩展程序。 确保图标的标签从“关闭”变为“打开”:
然后刷新您的应用程序,您的 API 请求现在应该可以工作了!”
它通过在全球范围内应用这个中间件对我有用
header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control -Allow-Headers', "Accept,authorization,Authorization, Content-Type"); } }对我来说,由于不同的原因我遇到了这个问题,远程域被添加到原点部署的应用程序完美地工作除了一个端点我遇到了这个问题:
Origin https://mai-frontend.vercel.app is not allowed by Access-Control-Allow-Origin. Status code: 500
和
Fetch API cannot load https://sciigo.herokuapp.com/recommendations/recommendationsByUser/8f1bb29e-8ce6-4df2-b138-ffe53650dbab due to access control checks.
在更新 Heroku 数据库表后,我发现我的 Heroku 数据库表不包含本地表的所有列,一切正常。
如果您使用 .NET 作为中间层,请清楚地检查路由属性,例如,
当它是这样的时候我有问题,
[Route("something/{somethingLong: long}")] //Space.
通过这个修复它,
[Route("something/{somethingLong:long}")] //No space
注释:这个问题是关于为什么Postman不受XMLHttpRequest相同的CORS限制的。 该问题与如何解决“无'Access-Control-Allow-Origin'...”错误无关。
请停止发布:
- 阳光下每种语言/框架的CORS配置。 而是找到您相关的语言/框架的问题。
- 允许绕过CORS的请求的第三方服务
- 用于关闭各种浏览器的CORS的命令行选项
我正在尝试通过连接到内置的RESTful API Flask使用JavaScript进行授权。 但是,当我发出请求时,出现以下错误:
XMLHttpRequest无法加载http:// myApiUrl / login 。 所请求的资源上没有“ Access-Control-Allow-Origin”标头。 因此,不允许访问原始“空”。
我知道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);
});
您使用的是 Google、Typekit 等的 Webfonts 吗? 您可以通过多种方式使用 Webfonts,例如 @font-face 或 CSS3 方法,出于相同的安全原因,某些浏览器(例如 Firefox 和 IE)可能会拒绝嵌入来自某些非标准 3rd 方 URL(例如您的博客)的字体。
为了解决您的 WordPress 博客的问题,只需将下面的内容放入您的 .htaccess 文件中。
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
来源: https : //crunchify.com/how-to-fix-access-control-allow-origin-issue-for-your-https-enabled-wordpress-site-and-maxcdn/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.