JSONP跨域请求原理及示例

来源:互联网 发布:商家给淘宝主播寄样品 编辑:程序博客网 时间:2024/05/17 09:40

Jsonp的跨域问题,再讲之前先说明一下什么是同源策略。

来自百度的介绍
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面。当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

如下:下表引自网络其他博客大牛

URL 说明 是否允许通信 http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许 http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许 http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许 http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许 http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许 http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上) 不允许 http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许

JSON和JSONP

    Json 和jsonp看起来好像啊,那么他们之间有什么联系吗?
    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,其具体格式及用法,我的这篇文章有介绍XML与JSON比较,并用AJAX传输XML/JSON数据
    JSONP 是JSON with Padding的简称,它是一个非官方的协议,它允许在服务器端集成Script tags返回客户端,通过javascript callback的形式实现跨域访问。(这是百度的说法,不懂没关系,我细细讲解)

    来看个小例子,大家还接标签吗,我们知道标签中的src属性可以引用本地资源,那么我要是访问网上的资源可以吗.行不行的通,试试看。举例,请求百度的logo吧,百度logo地址为:
https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png

        html页面

<div id="bdlog">    <img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"></div>

        结果展示:

这里写图片描述
        看到了吧,<img>中的src属性既可以请求本地图片,也可以请求网上资源。也就是说html中的src属性是支持跨域的。同理jsonp跨域请求也是利用src属性,只不过用的是<script></script>标签。
来看个jsonp的小例子
        jsonp.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>jsonp请求资源</title></head><body></body></html><script type="text/javascript" src="js/data.js

        data.js

console.log("我被jsonp请求了!");

        打开控制台,看一下:
这里写图片描述
        看,jsonp实现了本地数据的请求。如果我想请求服务器的数据该是怎样去实现呢?

JSONP的原理解析

jsonp.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>jsonp请求服务器数据</title></head><body></body></html><script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/02jsonp.php"></script>

        jsonp.php

<?php    echo "成功请求服务器!";?>

        结果如下:

这里写图片描述
        我们会发现页面请求了 jsonp.php页面,并且使用的是get方法。也就是说jsonp请求数据默认使用的是get方法。刚才我们再介绍jsonp的时候,说了一下 允许在服务器端集成Script tags返回客户端,通过javascript callback的形式实现跨域访问。
        那么我们继续改进html页面,在请求的url中添加一个?callback=test参数.其中test是写在html中的js函数
        jsonp.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>jsonp请求服务器数据</title></head><body></body></html><script>    function test(data) {        console.log("测试能否调用我这个test()函数");         console.log(data);    }</script><script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/jsonp.php?callback=test"></script>

        jsonp.php

<?php   // 获取到了 test.()   返回的是 test({"name":"jsonp","color":"green"});   echo $_GET['callback'].'({"name":"jsonp","color":"green"})'; ?>

结果是:
这里写图片描述
        通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url拼接一个callback参数,通过get方式请求服务器,服务器返回的数据若是json字符串将自动转化为js对象。所以jsonp是需要服务器端和客户端相互配合的。

        看图也许会明了一些:
这里写图片描述
        但是每次写

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>jQuery发送jsonp请求</title></head><body>    <input type="button" value="jQuery发送jsonp请求" id="jq_jsonp"></body></html><!--导入jQuery--><script type="text/javascript" src="js/jquery.min.js"></script><script>    $(function () {        $('#jq_jsonp').click(function () {            $.ajax({                url:'jQ_jsonp.php',                success:function (data) {                    console.log(data);                },                dataType:'jsonp'           })        })    })</script>

这里写图片描述
        可以发现,我们并没有写callback方法,jQuery自动帮我们封装了一个callback方法。
如果想要设置 自己的 回调函数 可以通过jsonpCallback 来设置 自己的名字

<script>    function myJSONPCallback(data) {        console.log("自己写的callback函数"+data);    }    $(function () {        $('#jq_jsonp').click(function () {            $.ajax({                url:'jQ_jsonp.php',                success:function (data) {                    console.log(data);                },                dataType:'jsonp',                jsonpCallback:"myJSONPCallback"            })        })    })</script>

        jQ_jsonp.php

<?php   echo $_GET['callback'].'("哈哈哈")'; ?>

这里写图片描述
这里写图片描述

        总结:JSONP(JSON with Padding)其本质是利用了<script src=""></script>标签具有可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成。**
只能以GET方式请求.**

原创粉丝点击