首页 > 代码库 > XHR的跨域请求和JSONP详解

XHR的跨域请求和JSONP详解

首先:什么是跨域?

 Cross Domain Request:从一个资源请求另一个资源,二者所在的请求地址不同,域名不同、端口号不同、请求协议不同。

它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

关于同源策略 这里推荐感兴趣的可以去 阮大的博客查看  阮一峰的个人博客

 

如何区分当前的请求是跨域请求?

在前端使用XHR对象发起请求时 浏览器 会将请求的发送地址和请求地址 的 协议  域名 端口号 做 字符串的匹配

技术分享

  提示:localhost和127.0.0.1也算跨域!

 

 浏览器允许跨域请求的情形

       IMG、LINK、SCRIPT、IFRAME ...

  浏览器禁止跨域请求的情形

       XHR  —— 浏览器处于安全考虑,禁用了XHR的跨域请求(其实服务器给出了响应消息,但浏览器不让使用)

 

如何解决浏览器的XHR跨域请求限制?

网上有关解决跨域请求的方法五花八门,这里仅仅列出常用的两种

1)、修改响应消息头部,添加Access-Control-Allow-Origin头部     服务器端添加响应头部  

2)、使用JSONP

JSONP:JSON with Padding,填充式JSON,与JSON完全两码事,是一种使用JSON数据的方式。意思是在JSON字符串左右添加函数名: doResponse( {"ename":"Tom", "age":20} );

JSONP是专用于解决XHR跨域限制一种手段。基本原理:使用动态创建的一个SCRIPT标签代替XHR发起异步请求,要求服务器必须返回application/javascript,立即在客户端执行——要执行的函数本体在客户端浏览器中声明。

 

  <script src="http://www.mamicode.com/x.php" async></script>

 

通常我们使用 script 标签获取并执行一段js代码 而scrip标签和所以拥有src属性的元素一样 不受浏览器同源策略的影响;

如果我们请求的是 doResponse( data ) 同时本地创建了一个 doResponse 函数 

结果 就是直接调用了 doResponse 函数  并在其参数组中获得了 我们需要的数据 data

 

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>...</title>
  <style>
  </style>
 </head>
 <body>
        <h3>使用JSONP解决浏览器跨域问题</h3>
        <hr>
        <button id="btn">发送jsonp请求</button>
        <script type="text/javascript" src="http://www.mamicode.com/js/jquery-1.11.3.js"></script>
        <script type="text/javascript">
            $("#btn").click(function(){
                var scri = docuemnt.createElement("script");
                s.src="http://localhost/AJAX/JSONP/1_jsonp.php";
                s.async=true;
            });
        </script>
 </body>
</html>

 

jQuery中如何使用JSONP发起异步请求:

(1) $.getJSON()

  用途1:使用XHR发起异步请求(不能跨域)

       $.getJSON(‘x.php‘, doResponse)

用途2:使用JSONP发起跨域异步请求

       $.getJSON(‘http://跨域地址/x.php?callback=?‘, doResponse)

(2) $.ajax() 推荐

  用途1:使用XHR发起异步请求(不能跨域)

       $.ajax({  })

  用途2:使用JSONP发起跨域异步请求

       $.ajax({ dataType: ‘jsonp‘ })

 

jquery 中极度简化了 script 获取后端响应数据的过程 但原理都是一样的;

 

XHR的跨域请求和JSONP详解