zoukankan      html  css  js  c++  java
  • 浏览器与服务器通信技术——跨域资源共享

    由于同源策略限制,默认情况下,使用XHR对象只能访问与包含它的页面位于同一个域(相同的协议、域名和端口)中的资源。要实现合理的跨域资源请求,有两种策略:1.跨域资源共享 ,2.利用DOM中能够执行跨域请求的功能。本文详述了第一种策略的实现方法。

    跨域资源共享(CORS)背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或相应是应该成功,还是应该失败。这种方法需要修改服务器代码。

    一. 简单请求的情况

    如果只是简单的使用GET或POST发送请求,并且没有自定义的头部,且主体内容是text/plain。在发送该请求时,需附加一个额外的origin头部,其中包含请求页面的源信息(协议、域名和端口),服务器会根据这个头部信息来决定是否给与响应。头部实例如下:

    origin:http://www.snsartme.com

    大部分浏览器都通过XMLHttpRequest对象实现了CORS的原生支持。在访问不同域的资源时,无需额外编写代码就会自动发送origin头部。只需要在open()方法中传入绝对URL即可,例如:

     1 var xhr=new XMLHttpRequest();
     2 xhr.onreadystatechange=function(){
     3     if(xhr.readyState==4){
     4         if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
     5             alert("成功"+xhr.responseText);
     6         }else{
     7             alert("失败"+xhr.responseText);
     8         }
     9     }    
    10 };
    11 
    12 xhr.open("get","http://www.somewhere.com/test.php",true);
    13 xhr.send(null);    

    如果服务器认为这个请求可以接受,就会在Access-Control-Allow-origin头部中回发相同的源信息(如果是公共资源,可以回发 ‘ * ’),比如在服务器的php代码中加入以下代码,来发送Access-Control-Allow-origin头部:

    header('Access-Control-Allow-origin:http:/www.snsartme.com');

    简单请求有如下一些限制:

    1. 不能使用setRequestHeader()方法设置自定义头部。

    2. 不能发送和接受cookie。

    3. 调用getALLResponseHeaders()方法总会返回空字符串。

    二、 预检请求

    预检请求(Preflighted Requests)必须首先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。“预检请求”的使用,可以避免跨域请求对服务器的用户数据产生无法预知的影响。OPTIONS方法发出的请求头部如下:

    Origin:与简单的请求相同。

    Access-Control-Request-Method:请求使用的方法

    Access-Control-Request-Headers:自定义的头部信息,多个头部以逗号分隔。

    当使用setRequestHeader()方法设置了自定义头部,或者请求方法不是get或post时,就会自动发送预检请求:

    1 var xhr=new XMLHttpRequest();
    2 xhr.open("get","http://www.somewhere.com/test.php",true);
    3 xhr.setRequestHeader("x-token", "I am x-token");
    4 xhr.send(null);

    服务器通过在响应中发送如下头部信息与浏览器沟通,php代码如下:

    1 header('Access-Control-Allow-origin:http://www.snsartme.com');
    2 header('Access-Control-Allow-Methods: GET,POST');//允许的方法 
    3 header('Access-Control-Allow-Headers:x-token'); //允许的头部
    4 header('Access-Control-Max-Age:7800'); //应该将预检请求缓存多长时间

    三、带凭据的请求

    默认情况下,跨域请求不提供凭据(cookie,HTTP认证及客户端SSL证明等)。通过将xhr的withCredentials属性设置为true,可以指定某个请求应该发送凭据。如果服务器接送带凭据的请求,会用下面的HTTP头部来响应。

    header('Access-Control-Allow-Credentials: true'); 

    下一篇会详解利用DOM中能够执行跨域请求的功能实现跨域资源访问,主要是jsonp技术

  • 相关阅读:
    C# winform 获取鼠标点击位置
    C# 读取带有命名空间的xml
    ImageUtility辅助类
    C# 读取XML
    C# 根据生日获取年龄
    C# 将 WebService 封装成动态库
    C# 生成条形码
    C# Ftp Client 基本操作
    C# SQL帮助类
    C# 解压缩文件
  • 原文地址:https://www.cnblogs.com/snsart/p/10907615.html
Copyright © 2011-2022 走看看