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
        ......
    }
    
  • 相关阅读:
    Linux学习篇(四):学习 gdb
    Linux学习篇(三):学习 gcc
    c#序列化感悟(重点讲讲二进制序列化)
    参数保存随笔
    写程序时try,catch查看报错的行号
    stram流char[]保存,支持中文,Filestram需要先转byte[]才能使用,但是性能更好《转载》
    c#序列化和反序列化《转载》
    如果两个测量设备出现相关性数据问题,且过度像素没区别?(打光效果一致),怎么办
    当Hobject类型出现内存泄漏爆炸增长的问题,怎么处理
    使用gige2500万相机时遇见的问题(条纹以及取图过久)
  • 原文地址:https://www.cnblogs.com/demingblog/p/8393511.html
Copyright © 2011-2022 走看看