# 跨域

# 什么是同源策略

端口号 协议 和域名 不一致,浏览器就会因为安全考虑,使用使用同源策略。

# jsonp 解决跨域

ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。

  • 当我们正常地请求一个 JSON 数据的时候,服务端返回的是一串 JSON 类型的数据,使用 JSONP 模式来请求数据的时候,服务端返回的是一段可执行的 JavaScript 代码。
使用JSONP,添加了一个script标签,标签的src指向了另一个域www.practice-zhao.com下的remote.js脚本
<script type="text/javascript">
    function jsonhandle(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="http://www.practice-zhao.com/remote.js"></script>


//服务端

jsonhandle({
    "age" : 15,
    "name": "John",

jsonp 缺点

  • jsonp 只支持 get 请求而不支持 post 请求
  • jsonp 只支持 get 请求,如果前端给后台传一个 json,后台是接收不到的,并且会报 415,如果前端要想把参数给后台,需要一个一个的拼。
  • 存在安全风险,防止 callback 参数恶意添加 script 标签,造成 xss 漏洞
  • 出现网络错误或者 404 等失败的回调函数并不会触发(通过 timeout 参数控制)

jsonp 不是 ajax,ajax 是通过 XMLHttpRequest 对象发送异步请求,而 jsonp 则是利用 js 标签天生具备的跨域能力来实现跨域资源访问。也就是说,虽然它的名字叫 JSONP(JSON with Padding),但它底层是通过 js 标签实现的,它跟 json 以及普通异步请求关系都不大,jquery 之所以把 jsonp 请求放到 ajax 方法里面,只是为了让 api 更方便调用而已。

//通过添加timeout设置请求超时,
$.ajax({
  url: '<%= SysUtils::TASK_CENTER_URL%>/all_tasks_h/verbose',
  type: 'GET',
  dataType: 'jsonp', // dataType为jsonp
  timeout: 5000, // 添加timeout参数
  success: function(data) { $('.result').text(JSON.stringify(data)); },
  error: function(jqXHR, textStatus) {
   // 此时textStatus为‘timeout’
   $('#main-content').text('error'); alert('JSONP error!');
  }
});