zoukankan      html  css  js  c++  java
  • Cross-Origin Resource Sharing(CORS)详解,CORS详解,CORS原理分析

    Keywords CORS, 跨域,JS跨域调用,Ajax CORS 跨域,跨域详解,CORS跨域原理

    Cross-Origin Resource Sharing详解

    Cross-Origin Resource Sharing 通常简称为:CORS。它是一种机制,这个机制使用了一个额外的HTTP响应头来赋予当前user-agent(浏览器)获得在当前源(origin)下使用非同源资源权限。这句话听起来很拗口,不易理解。但是请注意加粗字体所标记的两个关键字,这里的非同源就是Cross-Origin的概念,这里边的权限就是访问非同源的资源权限。下面我们弄清楚了这两个关键字的概念就理解了什么是Cross-Origin Resource Sharing。

    从一个例子说起

    假设我们现在在浏览器中输入 http://www.myapp.com/index.html 请求index.html页面。index.html中有一些文字信息,有一张图片
    http://www.somecloud.com/images/a.jpg ,和一个css文件 http://www.somecnd.com/a.css 。同时index.html的script节点中有如下的一个JavaScript方法。那么,图片、样式是否能够正常显示,getCrossRescource方法是否能正常执行呢?

    function getCrossRescource () {
      $.ajax({
         url:"http://www.other.com/goods.json",
         success:function(){
           // do something 
         }
      });
    }
    

    以chrome浏览器为例,假设我们开发者工具,然后在浏览器中输入上面的链接,我们可以看到,图片正常显示,样式也正常渲染。但是getCrossRescource ()方法并未执行成功。我们在开发者工具的制台面板里边会看到错误信息:

    Failed to load :http://www.other.com/goods.json

    No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.myapp.com is therefore not allowed access.

    通过错误信息我们得知:因为请求的资源不允许当前源https://www.myapp.com 访问,因为没有Access-Control-Allow-Origin头信息,为什么呢?

    这是因为:出于安全的原因,浏览器限制从脚本内发起跨源的HTTP请求,也就意味着限定了当前web应用程序只能请求与当前同域(同源)的HTTP资源,除非使用CORS头信息。——原来被浏览器限制了。那么那些请求会被限制呢?

    • 以跨站点的方式调用XMLHttpRequest或者Fetch API。
    • Web字体(用于CSS中@ font-face的跨域字体使用)
    • WebGL textures
    • 使用drawImage绘制到canvas的图像/视频帧。
    • 样式表(用于CSSOM访问)

    可以看到XMLHttpRequest遵循这个规则,而我们通常所使用的ajax方法就是基于XMLHttpRequest来实现的,所以在没有使用CORS头信息的的情况,跨源的getCrossRescource ()方法自然会无法顺利执行。而上文所提到的index.html里跨源的a.jpg、a.css不属于拦截目标,所以能够正常显示和渲染。

    说到这里我们弄清楚了机制的问题。这个机制约定了同源的问题,并阻止了规定的这些请求形式。还剩下一个同源的概念需要解释,那么什么叫做同源,什么叫做非同源呢?

    同源的定义

    给定两个页面,如果它们的协议、端口(如果指定了端口)、host都相同,则称之为同源。现在给出一个源连接和一些其他连接与这个源的比较,结合下表,我们来实际的理解一下这个概念。

    http://store.company.com/dir/page.html:

    URL 是否同源 原因
    http://store.company.com/dir2/other.html
    http://store.company.com/dir/inner/another.html
    https://store.company.com/secure.html 协议不同
    http://store.company.com:81/dir/etc.html 端口不同
    http://news.company.com/dir/other.html host不同

    CROS头信息设置

    以上文中的例子来说明,我们访问的是 http://www.myapp.com/index.html 页面,那么当前的origin就是 http://www.myapp.com。 而这个页面中的脚步请求的资源是 http://www.other.com/goods.json ,根据上文介绍的信息我们可以得知:这个是非同源的请求,且属于浏览器拦截名单里边的请求形式。所以我们需要通过设置CROS头信息来完成跨域调用。

    Access-Control-Allow-Origin 头信息设置

    本例中,我们需要在http://www.other.com/goods.json所对应的服务器代码中加入响应头:

    Access-Control-Allow-Origin: http://www.myapp.com

    设置完之后,当前的源http://www.myapp.com获得了访问数据的权限。这个时候我们可以在请求/响应头信息看到多了一些信息,大致如下:

    GET /...
    Host: ...
    User-Agent:  ...
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://www.myapp.com/index.html
    Origin: http://www.myapp.com
    
    --------------------------
    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 00:23:53 GMT
    Server: Apache/2.0.61 
    Access-Control-Allow-Origin: http://www.myapp.com
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: application/xml
    

    使用JSONP解决跨域

    除了使用设置CORS头信息,我们还可以使用JSONP来实现跨域调用。以Jquery为例,我们可以使用如下的写法来调用跨域资源:

    function corsTest(){
        $.ajax({
            type: "get",
            url: "http://other.host/data.json",
            dataType:"jsonp",
          	jsonp:"callback",
          	jsonpCallback:"callBack",
            ......
        })
    }
    function callBack(data){
        // do something
        ......
    }
    
  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/demingblog/p/8393511.html
Copyright © 2011-2022 走看看