跨域资源共享 (CORS) 概念

2022-01-15 00:00:00 cors jquery javascript ajax

我有一个关于跨域 JavaScript 概念的问题.

I have a question on the concept cross domain JavaScript.

有服务器(例如 amazon.com),只有在选定的域中才能使用其网络服务.所以肯定的是,如果我尝试从我当地使用他们的服务,我不能.我在我的控制台上得到了这个

There is server(ex amazon.com) where in only selected domains can use their web-service. So definitely, if I try to use their service, from my local, I cannot. I got this on my console

跨域请求被阻止:同源策略不允许读取远程资源在http://football20.myfantasyleague.com/2014/export?TYPE=名册&L=52761&W=&JSON=0.这可以通过将资源移动到同一域或启用 CORS.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://football20.myfantasyleague.com/2014/export?TYPE=rosters&L=52761&W=&JSON=0. This can be fixed by moving the resource to the same domain or enabling CORS.

PS:我也是用jquery跨域的方式,但是没用.

PS: I used jquery cross domain way too, but didnt work.

但是,如果选择的域中的某个域使用亚马逊的网络服务,有一个 JavaScript,如果我们将其包含在我们的 html 中,它就可以工作.

But if some domain who is among the selected ones, to use Amazon's webservice, has a JavaScript, which if we include in our html, it works.

<script src="http://example.com"></script>

他们有办法通过 Ajax 获得响应.

They have a method to get response by Ajax.

我的问题是:

  1. 当我们从 Internet url 引用 JavaScript 文件时会发生什么.我们的机器上是否运行了本地副本?
  2. 是否创建了 httpRequest,将有一个请求源作为我的域或 xyz.

推荐答案

前面的重要说明:如果另一端的服务器没有启用它,你的客户端 允许跨域 ajax 请求的代码.

Important note up front: If the server at the other end doesn't enable it, there's nothing you can do in your client-side code that will allow a cross-origin ajax request.

在回答你的问题之前,让我先介绍一下背景:

Let me give you a background before answering your question:

简单地说,同源安全策略确保来自一个来源的脚本不会从其他来源获取内容.现在为了解释起源的概念,让我引用维基百科同源安全政策的文章的部分内容:

Simply put, same-origin security policy makes sure that scripts from one origin may not fetch content from other origins. Now to explain you the concept of origin, let me quote part of the Wikipedia article of Same-Origin Security Policy:

下表概述了针对 URLhttp://www.example.com/进行检查的典型结果目录/page.html".

The following table gives an overview of typical outcomes for checks against the URL "http://www.example.com/dir/page.html".

Compared URL                                             Outcome  Reason
-------------------------------------------------------  -------  ----------------------
http://www.example.com/dir/page2.html                    Success  Same protocol and host
http://www.example.com/dir2/other.html                   Success  Same protocol and host
http://username:password@www.example.com/dir2/other.html Success  Same protocol and host
http://www.example.com:81/dir/other.html                 Failure  Same protocol and host but different port
https://www.example.com/dir/other.html                   Failure  Different protocol
http://en.example.com/dir/other.html                     Failure  Different host
http://example.com/dir/other.html                        Failure  Different host (exact match required)
http://v2.www.example.com/dir/other.html                 Failure  Different host (exact match required)
http://www.example.com:80/dir/other.html                 Depends  Port explicit. Depends on implementation in browser.

与其他浏览器不同,Internet Explorer 在计算来源时不包括端口,而是使用安全区域代替它.

Unlike other browsers, Internet Explorer does not include the port in the calculation of the origin, using the Security Zone in its place.

因此,例如,您的 JavaScript 无法从(也就是向其发出 HTTP 请求)Web 服务器下载任何东西,而不是它源自的服务器.这正是您不能向其他域发出 XmlHttpRequest(又名 AJAX)的原因.

So, for example, your JavaScript cannot download anything from (aka, make an HTTP request to) a web server other than the server it originated from. This is exactly why you cannot make XmlHttpRequests (aka AJAX) to other domains.

CORS 是一种另一端的服务器(不是浏览器中的客户端代码)可以放宽同源政策.

CORS is one way the server at the other end (not the client code in the browser) can relax the same-origin policy.

CORS 标准通过添加新的 HTTP 标头来工作,这些标头允许服务器向允许的源域提供资源.浏览器支持这些标头并遵守它们建立的限制.

The CORS standard works by adding new HTTP headers which allow servers to serve resources to permitted origin domains. Browsers support these headers and respect the restrictions they establish.

示例:假设您的网站是 http://my-cool-site.com,并且您在域 http:/中有第三方 API/third-party-site.com,您可以通过 AJAX 访问.

Example: Say your site is http://my-cool-site.com and, you have a third party API at domain http://third-party-site.com, which you can access via AJAX.

假设您的服务器 my-cool-site.com 中的一个页面向 third-party-site.com 发出了请求.通常,用户浏览器会根据 Same-Origin Security Policy 拒绝对您自己的域/子域以外的任何其他站点的 AJAX 调用.但是如果浏览器和第三方服务器支持 CORS,就会发生以下情况:

And let's assume that a page from your server my-cool-site.com made a request to third-party-site.com. Normally, users browser will decline AJAX calls to any other site other than your own domain/subdomain per the Same-Origin Security Policy. But if the browser and the third party server supports CORS, following things happen:

  • 浏览器将发送 Origin HTTP 标头到 third-party-site.com

Origin: http://my-cool-site.com

  • 如果第三方服务器接受来自您的域的请求,它将使用 Access-Control-Allow-Origin HTTP 标头进行响应:

  • If the third party server accepts requests from your domain, it will respond with an Access-Control-Allow-Origin HTTP header:

    Access-Control-Allow-Origin: http://my-cool-site.com
    

  • 要允许所有域,第三方服务器可以发送此标头:

  • To allow all domains, third party server can send this header:

    Access-Control-Allow-Origin: *
    

  • 如果你的网站不被允许,浏览器会报错.

  • If your site is not allowed, browser will throw an error.

    如果客户端有相当现代的浏览器支持CORS,以及您的第三方服务器也支持 CORS,CORS 对你很有用.

    If the client's have fairly modern browsers that support CORS, and your third party server supports CORS as well, CORS can be useful to you.

    在一些过时的浏览器(例如 IE8)中,您必须使用 Microsoft 特定的 XDomainRequest 对象而不是 XMLHttpRequest 来进行可以正常工作的调用CORS;这已经过时了,所有现代浏览器(包括来自微软的)都在 XMLHttpRequest 中处理 CORS.但是如果你需要支持过时的浏览器,这个页面 描述它:

    In some obsolete browsers (IE8, for instance), you have to use a Microsoft-specific XDomainRequest object instead of XMLHttpRequest to make a call that will work correctly with CORS; this outdated now, all modern browsers (including from Microsoft) handle CORS in XMLHttpRequest instead. But if you need to support obsolete browsers, this page describes it:

    要发出 CORS 请求,您只需在 Firefox 3.5+、Safari 4+ 和 Chrome 中使用 XMLHttpRequest 以及在 IE8+ 中使用 XDomainRequest 对象.使用 XMLHttpRequest 对象时,如果浏览器发现您正在尝试进行跨域请求,它将无缝触发 CORS 行为.

    To make a CORS request you simply use XMLHttpRequest in Firefox 3.5+, Safari 4+ and Chrome and XDomainRequest object in IE8+. When using XMLHttpRequest object, if the browser sees that you are trying to make a cross-domain request it will seamlessly trigger CORS behaviour.

    这是一个 javascript 函数,可帮助您创建跨浏览器 CORS 对象.

    Here is a javascript function that helps you create a cross browser CORS object.

    function createCORSRequest(method, url){
        var xhr = new XMLHttpRequest();
        if ("withCredentials" in xhr){
            // XHR has 'withCredentials' property only if it supports CORS
            xhr.open(method, url, true);
        } else if (typeof XDomainRequest != "undefined"){ // if IE use XDR
            xhr = new XDomainRequest();
            xhr.open(method, url);
        } else {
            xhr = null;
        }
        return xhr;
    }
    

    同样,这仅适用于过时的浏览器.

    Again, that's only necessary for obsolete browsers.

    以上原因是您无法从脚本中使用亚马逊网络服务的原因.而且亚马逊服务器只允许将他们的 JavaScript 文件下载到从选定域提供的页面.

    The above reasons are why you cannot use Amazon's web services from your script. And Amazon server will only allow downloading their JavaScript files to pages served from selected domains.

    回答您的编号问题:

      • 如果文件同源,浏览器将下载该文件.
      • 如果不是同源,则在 CORS 请求成功时会下载该文件.
      • 否则,下载脚本将失败.
      • 如果下载成功,JavaScript 文件的内容将被加载到浏览器的内存中,被解释并执行.

    查看 CORS 的描述以了解.

    See description on CORS to understand.

  • 相关文章