显然,我完全误解了它的语义。我想到了这样的事情:
客户端从下载JavaScript代码MyCode.jshttp://siteA-原产地。MyCode.js的响应标头包含Access Control Allow Origin:http://siteB,我认为这意味着允许MyCode.js对站点B进行跨源引用。客户端触发MyCode.js的一些功能,进而向http://siteB,这应该可以,尽管是跨源请求。
嗯,我错了。它根本不是这样工作的。所以,我已经阅读了跨源资源共享,并尝试阅读w3c推荐中的跨源资源分享。
有一点是肯定的——我仍然不明白我应该如何使用这个标题。
我完全控制站点A和站点B。如何使从站点A下载的JavaScript代码使用此标头访问站点B上的资源?
备注:我不想使用JSONP。
每当我开始思考CORS时,我对哪个站点托管标头的直觉是错误的,正如您在问题中所描述的那样。对我来说,思考同源政策的目的是有帮助的。
同源策略的目的是保护您免受siteA.com上的恶意JavaScript访问您选择仅与siteB.com共享的私人信息。如果没有同源策略,siteA.com作者编写的JavaScript可能会让您的浏览器使用您的siteB.com身份验证cookie向siteB.com发出请求。这样,siteA.com可能会窃取您与siteB.com共享的秘密信息。
有时您需要跨域工作,这就是CORS的作用所在。CORS放宽了siteB.com的同源策略,使用Access Control Allow origin标头列出其他受信任运行可与siteB.com交互的JavaScript的域(siteA.com)。
要了解哪个域应该为CORS标头提供服务,请考虑这一点。您访问malious.com,其中包含一些试图向mybank.com发出跨域请求的JavaScript。应该由mybank.com而不是malious.com来决定它是否设置CORS标头,以放宽同源策略,从而允许maliouss.com中的JavaScript与之交互。如果malious.com可以设置自己的CORS标头,允许自己的JavaScript访问mybank.com,这将完全取消同源策略。
我认为我直觉不好的原因是我在开发网站时的观点。这是我的网站,有我所有的JavaScript。因此,它没有做任何恶意的事情,应该由我来指定我的JavaScript可以与哪些其他站点交互。事实上,我应该思考:哪些其他网站的JavaScript正在尝试与我的网站交互,我应该使用CORS来允许它们?
根据我自己的经验,很难找到一个简单的解释,为什么CORS甚至是一个问题。
一旦你明白了为什么会出现,标题和讨论就会变得更加清晰。我会在几行字里尝试一下。
都是关于饼干的。Cookie按其域存储在客户端上。
一个例子:在你的电脑上,有一个你的bank.com的cookie。也许你的会话就在那里。
要点:当客户端向服务器发出请求时,它将发送存储在该请求的域下的cookie。
您已在浏览器上登录到yourbank.com。您请求查看您的所有帐户,并为yourbank.com发送cookie。yourbank.com收到一堆cookie,并发回其响应(您的帐户)。
如果另一个客户机向服务器发出跨源请求,则会像以前一样发送这些cookie。如罗。
你浏览到malicious.com。malicious向不同的银行发出一系列请求,包括yourbank.com。
由于cookie按预期进行了验证,服务器将授权响应。
这些饼干被收集起来并一起发送——现在,malious.com收到了您银行的回复。
诶呀
现在,一些问题和答案变得显而易见:
“我们为什么不阻止浏览器这样做?”是的。这是CORS。“我们怎么解决?”让服务器告诉请求CORS正常。
对于带有Angular的.NET Core 3.1 API
Startup.cs:添加CORS
//SERVICES
public void ConfigureServices(IServiceCollection services){
//CORS (Cross Origin Resource Sharing)
//=====================================
services.AddCors();
}
//MIDDLEWARES
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
//ORDER: CORS -> Authentication -> Authorization)
//CORS (Cross Origin Resource Sharing)
//=====================================
app.UseCors(x=>x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200"));
app.UseHttpsRedirection();
}
}
控制器:为授权控制器启用CORS
//Authorize all methods inside this controller
[Authorize]
[EnableCors()]
public class UsersController : ControllerBase
{
//ActionMethods
}
使用React和Axios,将代理链接连接到URL,并添加标头,如下所示:
https://cors-anywhere.herokuapp.com/+您的API URL
只需添加代理链接即可,但它也可能再次引发“无访问”错误。因此,最好添加一个标题,如下所示。
axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
.then(response => console.log(response:data);
}
警告:不得用于生产
这只是权宜之计。如果你在纠结为什么你不能得到回应,你可以使用这个。但这同样不是生产的最佳答案。
1.客户端从http://siteA-原产地。
进行下载的代码-您的html脚本标记或来自javascript的xhr或其他任何东西-来自,比方说,http://siteZ.而且,当浏览器请求MyCode.js时,它会发送一个Origin:头,上面写着“Origin:http://siteZ“,因为它可以看到您正在请求siteA和siteZ!=siteA。(您不能停止或干扰此操作。)
2.MyCode.js的响应头包含Access Control Allow Origin:http://siteB,我认为这意味着允许MyCode.js对站点B进行跨源引用。
不。这意味着,只有站点B才允许执行此请求。因此,您从siteZ请求MyCode.js时会出现错误,浏览器通常不会提供任何信息。但是如果你让你的服务器返回A-C-A-O:siteZ,你会得到MyCode.js。或者如果它发送'*',这会起作用,这会让所有人都进来。或者如果服务器总是从Origin:header发送字符串。。。但是为了安全起见,如果你害怕黑客,你的服务器应该只允许短名单上的来源,允许他们提出这些请求。
然后,MyCode.js来自siteA。当它向站点B发出请求时,它们都是跨源的,浏览器发送origin:siteA,站点B必须接收站点A,识别它在允许的请求者的短列表中,然后发送A-C-A-O:siteA。只有这样,浏览器才会让脚本获得这些请求的结果。