Mr *_*edi 2320 javascript jquery same-origin-policy cors flask-restless
我试图通过连接到Flask内置的RESTful API来使用JavaScript进行授权.但是,当我发出请求时,我收到以下错误:
XMLHttpRequest无法加载http:// myApiUrl/login.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许原点'null'访问.
我知道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);
});
Run Code Online (Sandbox Code Playgroud)
MD.*_*oob 1250
如果我理解正确,那么您正在将XMLHttpRequest发送到与您的页面不同的域.因此浏览器会阻止它,因为出于安全原因,它通常允许同一来源的请求.当您想要执行跨域请求时,您需要做一些不同的事情.关于如何实现这一目标的教程是使用CORS.
当您使用邮递员时,他们不受此政策的限制.引自Cross-Origin XMLHttpRequest:
常规网页可以使用XMLHttpRequest对象从远程服务器发送和接收数据,但它们受到相同原始策略的限制.扩展不是那么有限.扩展可以与其来源之外的远程服务器通信,只要它首先请求跨源权限即可.
shr*_*uti 521
这不是生产修复或者必须向客户端显示应用程序时,这仅在UI和后端开发 位于不同服务器上并且在生产中它们实际上位于同一服务器上时才有用.例如:在为任何应用程序开发UI时,如果需要在本地测试它指向后端服务器,那么这是一个完美的修复.对于生产修复,必须将CORS头添加到后端服务器以允许跨源访问.
简单的方法是在谷歌浏览器中添加扩展名以允许使用CORS进行访问.
只要您希望不允许访问"access-control-allow-origin"标头请求,只需启用此扩展.
要么
在Windows中,将此命令粘贴到运行窗口中
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Run Code Online (Sandbox Code Playgroud)
这将打开一个新的Chrome浏览器,允许访问没有'access-control-allow-origin'标头请求.
Gav*_*vin 339
如果你可以回应JSON,那么尝试使用JSONP(注意结尾的P)来表达域之间的说话:
$.ajax({
type: "POST",
dataType: 'jsonp',
...... etc ......
Run Code Online (Sandbox Code Playgroud)
在此处了解有关使用JSONP的更多信息:
JSONP的出现 - 本质上是一个双方同意的跨站点脚本黑客 - 为强大的内容混搭打开了大门.许多着名网站都提供JSONP服务,允许您通过预定义的API访问其内容.
sha*_*rif 216
如果您使用PHP,则解决起来非常简单.只需在处理请求的PHP页面的开头添加以下脚本:
<?php header('Access-Control-Allow-Origin: *'); ?>
Run Code Online (Sandbox Code Playgroud)
警告:这包含您的PHP文件的安全问题,攻击者可以调用它.您必须使用会话和cookie进行身份验证,以防止您的文件/服务遭受此攻击.您的服务容易受到跨站点请求伪造(CSRF)的攻击.
如果您使用的是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"
},
Run Code Online (Sandbox Code Playgroud)
yos*_*osh 178
我希望很久以前有人和我分享这个网站http://cors.io/与构建和依赖我自己的代理相比,它可以节省大量时间.但是,当您转向生产时,拥有自己的代理是最好的选择,因为您仍然可以控制数据的所有方面.
一切你需要的:
https://cors.io/?http://HTTP_YOUR_LINK_HERE
Ngu*_*ran 75
如果您使用的是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();
});
Run Code Online (Sandbox Code Playgroud)
更多信息:ExpressJS上的CORS
Geo*_*ton 57
因为
$ .ajax({type:"POST" - 调用OPTIONS
$ .post( - 调用POST
两者都是不同的Postman称之为"POST",但当我们称之为"OPTIONS"时
对于c#web服务 - webapi
请在<system.webServer>标记下的web.config文件中添加以下代码.这会奏效
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Run Code Online (Sandbox Code Playgroud)
请确保您在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");
}
});
Run Code Online (Sandbox Code Playgroud)
Angular 4问题请参考:http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/
注意:如果您正在寻找从第三方网站下载内容,那么这对您没有帮助.您可以尝试以下代码,但不能使用JavaScript.
System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");
Run Code Online (Sandbox Code Playgroud)
Kam*_*ski 31
在下面作为 API 的调查中,我使用http://example.com而不是您问题中的http://myApiUrl/login,因为第一个工作正常。
我假设您的页面位于http://my-site.local:8088 上。
你看到不同结果的原因是邮递员:
Host=example.com
(您的 API)Origin
这类似于当站点和 API 具有相同域时浏览器发送请求的方式(浏览器也设置了标头项Referer=http://my-site.local:8088
,但我在 Postman 中没有看到它)。当没有设置Origin
header 时,通常服务器默认允许这样的请求。
这是 Postman 发送请求的标准方式。但是当您的站点和 API 具有不同的域时,浏览器会发送不同的请求,然后发生CORS并且浏览器会自动:
Host=example.com
(你的 API)Origin=http://my-site.local:8088
(您的网站)(标头与Referer
具有相同的值Origin
)。现在在 Chrome 的控制台和网络选项卡中,您将看到:
当你有Host != Origin
这个 CORS 时,当服务器检测到这样的请求时,它通常默认阻止它。
Origin=null
当您从本地目录打开 HTML 内容时设置,并发送请求。同样的情况是,当您在 . 中发送请求时<iframe>
,如下面的代码片段所示(但此处Host
根本没有设置标头) - 通常,在 HTML 规范中说不透明来源的任何地方,您都可以将其转换为Origin=null
. 您可以在此处找到有关此的更多信息。
fetch('http://example.com/api', {method: 'POST'});
Run Code Online (Sandbox Code Playgroud)
Look on chrome-console > network tab
Run Code Online (Sandbox Code Playgroud)
如果您不使用简单的 CORS 请求,通常浏览器还会在发送主要请求之前自动发送一个 OPTIONS 请求——更多信息在此处。下面的片段显示了它:
fetch('http://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json'}
});
Run Code Online (Sandbox Code Playgroud)
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)
Run Code Online (Sandbox Code Playgroud)
您可以更改服务器的配置以允许 CORS 请求。
这是一个示例配置,它在 nginx(nginx.conf 文件)上打开CORS - 在设置always/"$http_origin"
nginx 和"*"
Apache 时要非常小心- 这将解除对任何域的 CORS 的阻止。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是在 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"
Run Code Online (Sandbox Code Playgroud)
Gop*_*ath 23
应用 CORS 限制是由服务器定义并由浏览器实现的安全功能。
浏览器查看服务器的 CORS 策略并遵守它。
但是,Postman 工具并不关心服务器的 CORS 策略。
这就是 CORS 错误出现在浏览器中,而不是 Postman 中的原因。
Sta*_*kin 17
您正在向不同的域发出XMLHttpRequest,例如:
some-domain.com
some-different-domain.com
域名的这种差异会触发称为SOP(同源策略)的CORS(跨源资源共享)策略,该策略强制在Ajax 、XMLHttpRequest 和其他 HTTP 请求中使用相同的域(因此是Origin)。
为什么当我通过 Chrome 扩展程序 Postman 发出请求时它会起作用?
客户端(大多数浏览器和开发工具)可以选择强制执行同源策略。
大多数浏览器强制执行同源策略,以防止与CSRF(跨站请求伪造)攻击相关的问题。
Postman作为一种开发工具选择不强制执行 SOP,而某些浏览器强制执行,这就是为什么您可以通过 Postman 发送请求,而您无法使用浏览器通过 JS 通过 XMLHttpRequest 发送请求。
小智 15
如果您想在 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}`));
Run Code Online (Sandbox Code Playgroud)
以上是可以充当代理服务器的示例代码(需要节点 Js)。例如:如果我想https://www.google.com
正常获取CORS 错误,但现在由于请求是通过本地托管在端口 3000 的代理服务器发送的,代理服务器Access-Control-Allow-Origin
在响应中添加标头,不会有任何问题。
向 http://localhost:3000/fetch?url= 发送 GET 请求Your URL here
,而不是直接将请求发送到您要获取的 URl。
Your URL here
代表您希望获取的 URL,例如: https://www.google.com
Kms*_*Kms 14
在不同的用例中遇到相同的错误。
用例:在 Chrome 中尝试以angular调用 Spring REST端点时。
解决方案:在各个控制器类的顶部添加@CrossOrigin("*")注释。
Jac*_*esB 14
您得到的错误是由 CORS 标准造成的,该标准对 JavaScript 如何执行 ajax 请求设置了一些限制。
CORS 标准是一种客户端标准,在浏览器中实现。因此,阻止调用完成并生成错误消息的是浏览器 - 而不是服务器。
Postman 没有实现 CORS 限制,这就是为什么从 Postman 发出相同调用时您看不到相同错误的原因。
为什么Postman 不实施 CORS?CORS 定义了与发起请求的页面的来源(URL 域)相关的限制。但是在 Postman 中,请求不是来自带有 URL 的页面,因此 CORS 不适用。
Gan*_*nan 12
如果你不想:
并且您确定您的服务器已启用CORS(请在此处测试CORS:http://www.test-cors.org/)
然后你需要在你的请求中传入origin参数.此来源必须与您的浏览器与您的请求一起发送的来源相匹配.
你可以在这里看到它:http: //www.wikinomad.com/app/detail/Campgrounds/3591
编辑功能将GET和POST请求发送到其他域以获取数据.我设置了解决问题的origin参数.后端是一个mediaWiki引擎.
tldr:在你的调用中添加"origin"参数,这些参数必须是浏览器发送的Origin参数(你不能欺骗origin参数)
小智 10
当我使用AngularJS访问我的API时,我遇到了问题.相同的请求在SoapUI 5.0和ColdFusion中有效.我的GET方法已经有了Access-Control-Allow-Origin标头.
我发现AngularJS提出了"试用"OPTIONS请求.默认情况下,ColdFusion会生成OPTIONS方法,但它没有太多,具体来说这些标头.响应OPTIONS调用生成错误,而不是我故意调用GET.在我将API 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>
Run Code Online (Sandbox Code Playgroud)
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/ code.
与此处提到的其他开放代理(其中一些至少似乎不再可用)一样,它的工作方式是,而不是让您的客户端代码直接发送请求,例如,http://foo.com
您将其发送到https://cors-anywhere.herokuapp.com/http://foo.com
和代理Access-Control-*
向浏览器看到的响应添加必要的标头.
从服务器请求响应时,我有以下配置,导致相同的错误.
服务器端: SparkJava - >提供REST-API
客户端: ExtJs6 - >提供浏览器呈现
在服务器端,我不得不将此添加到响应中:
Spark.get("/someRestCallToSpark", (req, res) -> {
res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working
return "some text";
});
Run Code Online (Sandbox Code Playgroud)
在客户端,我不得不将此添加到请求中:
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")}
});
Run Code Online (Sandbox Code Playgroud)
您可以通过使用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);
},
});
Run Code Online (Sandbox Code Playgroud)
这是带有解释的链接:https://vverma.net/fetch-any-json-using-jsonp-and-yql.html
出于浏览器测试目的:
Windows - 运行:
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
Run Code Online (Sandbox Code Playgroud)
上面的命令将禁用 Chrome Web 安全性。因此,例如,如果您在本地项目上工作并在尝试发出请求时遇到 CORS 策略问题,则可以使用上述命令跳过此类错误。基本上它会打开一个新的 chrome 会话。
如果您正在使用Entity Framework,即使您已CORS
启用,有时也会抛出此错误.我发现错误的发生是因为缺少查询的最终确定.我希望这会在同样的情况下帮助其他人.
以下代码可以抛出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,
});
}
Run Code Online (Sandbox Code Playgroud)
要修复它,需要在查询结束时.ToList()
或.FirstOrDefault()
在查询结束时进行终结调用,如下所示:
using (DBContext db = new DBContext())
{
return db.Customers.Select(x => new
{
Name = x.Name,
CustomerId = x.CustomerId,
}).ToList();
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我使用的是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();
}
Run Code Online (Sandbox Code Playgroud)
我可以使用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>
Run Code Online (Sandbox Code Playgroud)
https://httpd.apache.org/docs/2.4/mod/core.html#filesmatch
如果您的网关超时太短并且您正在访问的资源的处理时间比超时长,您也可能会收到此错误。对于复杂的数据库查询等,可能会出现这种情况。因此,上述错误代码可以掩盖这个问题。只需检查错误代码是否为 504,而不是Kamil 的答案或其他内容中的 404。如果是 504,则增加网关超时可能会解决问题。
\n就我而言,可以通过在Internet\xc2\xa0Explorer浏览器中禁用同源策略 (CORS) 来删除 CORS 错误,请参阅如何禁用同源策略 Internet Explorer。这样做之后,日志中就是纯粹的504错误。
\n 归档时间: |
|
查看次数: |
3991574 次 |
最近记录: |