jsonp及cors

一. jsonp实现原理是利用script标签可以获取不同源资源的特点,来达到跨域访问某个资源的目的。具体行为如下:

  1. 创建一个script标签,将请求地址写入它的src属性,将这个script外链插入head标签中;
  2. 声明一个回调函数callback,函数名和请求地址中的一致;
  3. 请求地址的内容是一个以json对象为参数的执行函数callback;
  4. 当script资源载入时,callback开始执行,将json数据输出。
  5. jsonp其实就是json padding,而在json数据外包裹它的那个函数,就是padding。
// 简单的mock jsonp

var mockJsonp = function(url) {
    var ele = document.createElement('script');
    var head = document.getElementsByTagName('head')[0];
    ele.src = url;
    head.appendChild(ele);
}
mockJsonp('./index.js');
function callback(data){
    console.log(data);
}

// index.js

callback("name": "xxx", "age": "20");

二. jq中的ajax请求数据格式为jsonp时,会发生以下操作:先构造一个script标签,然后注册一个onload的回调,最后将构造好的script标签insert进去;insert完成之后,会触发onload回调,其中又将前面插入的script标签去掉了。其中的 代码 callback( 200, "success" ) 其实就是触发 ajax 的jsonp成功时的success回调函数,callback函数其实是一个 done 函数。

三. jsonp跨域只能是get请求,jq在封装jsonp跨域时,不论我们指定的是get还是post,他统一换成了get请求。

四. cors(Cross-Origin Resource Sharing)跨域资源共享:

     1. 简单请求:请求方式是get、post、head之一,头信息不超过 Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(application/x-www-form-urlencoded、multipart/form-data、text/plain)

  • 发出cors请求,会在头部带上Origin(说明本次请求来自那个源),服务器响应成功会返回Access-Control-Allow-Origin为请求的源或*;
  • 请求时设置withCredentials为true可以带上cookie和证书信息之类的,服务器指定Access-Control-Allow-Credentials为true;
  • 如果要发送cookie,Access-Control-Allow-Origin就不能为*,二必须设置为与请求一致的域名;且Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传。

     2 . 非简单请求:不同时满足简单请求的条件

  • 会在正式通信之前,增加一次HTTP查询请求,即“预检”请求;
  • “预检”请求方法是OPTIONS,表示这个请求是用来询问的;头信息里面,关键字段是Origin;还包括Access-Control-Request-Method请求方法,Access-Control-Request-Headers需要额外发送的头信息;
  • 如果检查了请求头信息后允许访问,则会返回Access-Control-Allow-Origin,Access-Control-Allow-Headers(支持的所有头信息字段),Access-Control-Allow-Credentials,Access-Control-Max-Age(本次预检有效期);
  • 通过了“预检”请求,以后就跟简单请求一样了。

四. 其他跨域方式

  1. 修改document.domain,将子域和主域的document.domain设为同一个主域;
  2. window.name,每个页面都对window.name有读写的权限,window.name持久存在在一个窗口载入过的所有页面中;
  3. window.postMessage;
  4. 要在父页面访问iframe内子页面的全局变量:window.frames[id].变量名 或 document.getElementById(id).contentWindow.变量名。
  5. nginx反向代理
posted @ 2017-06-20 20:08  we are young  阅读(344)  评论(0编辑  收藏  举报