我正在尝试使用JavaScript进行授权,方法是连接到Flask中内置的RESTful API . 但是,当我发出请求时,我收到以下错误:
XMLHttpRequest无法加载http:// myApiUrl / login . 请求的资源上不存在“Access-Control-Allow-Origin”标头 . 因此不允许原点'null'访问 .
我知道API或远程资源必须设置 Headers ,但为什么在我通过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);
});
30 回答
使用Ajax存在跨域问题 . 您必须确保在相同的
http://
路径上访问您的文件而没有www.
(或从http://www.
访问并发布到相同的路径,包括www.
),当通过www.
路径访问时,浏览器认为该路径是另一个域,因此您可以看到问题所在是 . 您正在发布到其他域,并且浏览器会因原始问题阻止流 .如果API未放置在您请求的同一主机上,则会阻止该流,您需要找到另一种与API通信的方式 .
如果我理解正确,那么您正在使用与您的网页不同的域名.1735905_ . 因此浏览器会阻止它,因为出于安全原因,它通常允许同一来源的请求 . 当您想要执行跨域请求时,您需要做一些不同的事情 . 关于如何实现这一目标的教程是Using CORS .
当您使用邮递员时,他们不受此政策的限制 . 引自Cross-Origin XMLHttpRequest:
简单的方法是在谷歌浏览器中添加扩展名以允许使用CORS进行访问 .
(https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US)
只要您希望允许访问没有 'access-control-allow-origin' 标头请求,只需启用此扩展程序 .
Or
在Windows中,将此命令粘贴到 run 窗口中
这将打开一个新的 chrome 浏览器,允许访问没有 'access-control-allow-origin' 标头请求 .
如果你可以回复JSON,那么尝试使用JSONP(注意结尾的 P )在域名之间说话:
了解有关使用JSONP的更多信息here:
如果您正在使用PHP,那么解决起来非常简单 . 只需在处理请求的PHP页面的开头添加以下脚本:
Warning: 这包含您的PHP文件的安全问题,攻击者可以调用它 . 您必须使用会话和cookie进行身份验证,以防止您的文件/服务遭受此攻击 . 您的服务容易受到cross-site request forgery(CSRF)的攻击 .
如果您正在使用Node-red,则必须通过取消注释以下行来允许
node-red/settings.js
文件中的CORS:我希望有人在很久以前与我分享这个网站http://cors.io/与构建和依赖我自己的代理相比,它可以节省大量时间 . 但是,当您转向 生产环境 时,拥有自己的代理是最好的选择,因为您仍然可以控制数据的所有方面 .
一切你需要的:
https://cors.io/?http://HTTP_YOUR_LINK_HERE
如果您使用Node.js,请尝试:
更多信息:CORS on ExpressJS
因为
$.ajax({type: "POST" - 致电 OPTIONS
$.post( - 致电 POST
两者都是不同的Postman称之为“POST”,但当我们称之为“OPTIONS”时
For c# web services - webapi
请在您的web.config中添加以下代码<system.webServer>标记下的文件 . 这会奏效
请确保您在ajax呼叫中没有犯任何错误
jQuery的
Angular 4问题请参考:http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/
Note: 如果您正在寻找下载内容 from third party website ,那么 this will not help you . 您可以尝试以下代码,但不能使用JavaScript .
试试XDomain,
如果你不想:
在Chrome中停用网络安全
使用JSONP
使用第三方网站重新路由您的请求
并且您确定您的服务器已启用CORS(此处测试CORS:http://www.test-cors.org/)
然后你需要在你的请求中传入origin参数 . 此来源必须与您的浏览器与您的请求一起发送的来源相匹配 .
你可以在这里看到它:http://www.wikibackpacker.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 makes a "trial" OPTIONS request . 默认情况下,ColdFusion会生成OPTIONS方法,但它没有太多,具体来说这些标头 . 响应OPTIONS调用生成错误,而不是我故意调用GET . 在我将API OPTIONS方法添加到我的API后,问题已得到解决 .
从服务器请求响应时,我有以下配置,导致相同的错误 .
Server-side: SparkJava - >提供REST-API
Client-side: ExtJs6 - >提供浏览器渲染
在 server-side 我必须将此添加到响应中:
在 client-side 我必须将此添加到请求中:
基于shruti's answer,我创建了一个带有所需参数的Chrome浏览器快捷方式:
您可以通过使用YQL通过Yahoo的服务器代理请求来绕过问题 . 它只是几行代码:
这是带有解释的链接:https://vverma.net/fetch-any-json-using-jsonp-and-yql.html
https://github.com/Rob--W/cors-anywhere/提供(Node.js)代码,您可以使用它来设置和运行自己的CORS代理 . 它主动维护并提供许多功能来控制代理行为,而不仅仅是基本发送正确的
Access-Control-*
响应头 .https://developer.mozilla.org/en-US/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-*
标头添加到浏览器看到的响应中 .如果您使用Entity Framework,即使启用了
CORS
,有时也会抛出此错误 . 我发现错误的发生是因为缺少查询的最终确定 . 我希望这会在同样的情况下帮助其他人 .以下代码可能会抛出
XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.
错误:要解决此问题,需要在查询结束时进行
.ToList()
或.FirstOrDefault()
之类的终结调用,如下所示:在我的情况下,我使用的是JEE7 JAX-RS应用程序,并且以下技巧对我来说非常有效:
我成功地能够使用htaccess解决(在我的情况下使用字体),但很明显,OP的要求稍有不同 . 但您可以使用FileMatch模式并添加任何类型的扩展名,以便它不会产生交叉错误 .
https://httpd.apache.org/docs/2.4/mod/core.html#filesmatch
热门问题 - 如果你已经阅读了这篇文章而另外没有其他任何内容有助于另一件事 . 如果您有一个CDN,如Akamai,Limelight或类似的CDN,您可能需要检查您拥有的资源URI的缓存密钥 . 如果它不包含Origin标头值,则可能在从另一个Origin请求时返回缓存的响应 . 我们只花了半天时间调试这个 . CDN配置已更新为仅包含我们的一些选定域的Origin值,并将其设置为null . 这似乎有效,并允许来自我们已知域的浏览器查看我们的资源 . 当然所有其他答案都是到达这里的先决条件,但如果CDN是您浏览器的第一跳,则需要查看 .
在我们的案例中,我们可以看到一些请求进入我们的服务但不是几乎没有网站发送的卷 . 这向我们指出了CDN . 我们能够返回并看到原始请求是从直接请求提供的,而不是浏览器AJAX调用的一部分,并且不包括响应头Access-Control-Allow-Origin . 显然,CDN缓存了这个值 . Akamai CDN配置调整将原始请求标头值视为匹配的一部分似乎已使其适用于我们 .
对于GoLang API:
首先你可以看看MDN CORS Doc来了解CORS是什么 . 据我所知,CORS是否允许Origin Of Request访问Server Resource .
您可以通过在服务器响应的
Header
设置Access-Control-Allow-Origin
来限制哪个请求源可以访问服务器 .例如,在服务器响应中设置以下标头意味着只有从
http://foo.example
发送的请求才能访问您的服务器:以及允许从任何来源(或域)发送的请求:
正如我在错误消息中所知,
requested resource
表示服务器的资源,因此No 'Access-Control-Allow-Origin' header is present on the requested resource.
表示您未在服务器响应中设置Access-Control-Allow-Origin
标头,或者您可能设置但请求的来源不是Access-Control-Allow-Origin
中的列表,因此不允许请求访问:在GoLang中,我使用
gorilla/mux
包在localhost:9091
构建API服务器,并通过将"Access-Control-Allow-Origin", "*"
添加到响应头来允许CORS:我在客户端使用JavaScript,在
localhost:9092
上,Chrome的请求可以成功从服务器localhost:9091
获取"OKOK" .此外,您可以通过
Fiddler
等工具检查您的请求/响应标头 .如果您从浏览器收到此错误消息:
当您尝试向远程服务器执行Ajax POST / GET请求时,请忘记这个简单的修复:
您真的需要,特别是如果您只使用JavaScript来执行Ajax请求,内部代理将接收您的查询并将其发送到远程服务器 .
首先在您的JavaScript代码中,对您自己的服务器执行Ajax调用,例如:
然后,创建一个名为proxy.php的简单PHP文件来包装POST数据,并将它们作为参数附加到远程URL服务器 . 我举例说明了如何使用Expedia Hotel搜索API绕过此问题:
通过做:
您只是在执行相同的查询,但在服务器端,之后,它应该可以正常工作 .
Answer copied and pasted from NizarBsb
很多时候,这种情况发生在我从javascript到我的php api,因为有几个原因之一 . 我忘了把
<?php header('Access-Control-Allow-Origin: *'); ?
放在一边 . 这对跨子域访问很有帮助 . 另一个原因是因为在jQuery ajax请求中我指定了一个特定的dataType并返回一个不同的dataType,所以它抛出了一个错误 .此错误的最后和最突出的原因是您请求的页面上存在解析错误 . 如果您在浏览器中点击该页面网址的可能性很大,您将看到一个解析错误,并且您将有一个行号来解决该问题 .
我希望这有帮助有人 . 我每次花了一段时间来调试这个,我希望我有一份要核实的清单 .
我在Angular中用
$http.get
得到了这个错误 . 我需要使用 $http.jsonp 代替 .在我的网站上(基于.NET)我刚刚添加了这个:
非常感谢this视频 .
CORS适合你 .
CORS是“跨源资源共享”,是一种发送跨域请求的方法 . 现在,XMLHttpRequest2和Fetch API都支持CORS .
但它有其局限性 . 服务器需要具体声明 Access-Control-Allow-Origin ,并且不能设置为'*' .
如果你想任何来源可以发送请求给你,你需要JSONP(也需要设置 Access-Control-Allow-Origin ,但可以'*') .
对于很多请求方式,如果你不知道该选择什么,我认为你需要一个功能齐全的组件来做到这一点 . 让我介绍一个简单的组件 catta
如果您使用的是现代浏览器(> Internet Explorer9,Chrome,Firefox,Edge等),建议您使用简单但美观的组件 https://github.com/Joker-Jelly/catta . 它没有依赖关系,小于3 KB,它支持Fetch,Ajax和JSONP,具有相同的死语法和选项 .
它还支持导入项目的所有方式,如ES6模块,CommonJS甚至HTML中的
<script>
.这些答案中的大多数都告诉用户如何将CORS标头添加到他们控制的服务器中 .
但是,如果您需要来自服务器的数据而无法在网页中控制,则一种解决方案是在页面上创建脚本标记,将src属性设置为不具有CORS标头的api endpoints ,然后加载该数据到页面上:
如果你想在后端(在Flask中)修复它,而不是在前端,我会完全推荐Flask CORS python包 . Flask Cors
使用app.py中的一个简单行,您可以自动插入标准允许任何原始 Headers ,或根据需要自定义它 .
对于
application_controller.rb
中的Ruby on Rails服务器,添加以下内容:No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://sx.xyz.com' is therefore not allowed access.
我在Ajax响应中也遇到了与跨域数据交换类似的问题 error undefined . 但 Headers 中的回复是 Status Code:200 OK
The solution to get around it: 在我的情况下,它是通过Ajax将函数checkapikey()调用到另一个域并获取响应数据到响应的位置:
为完整起见,Apache允许角色: