扫码关注官方订阅号
js跨域请求不同域名下的数据,如果是放在script标签中,直接用src属性就可以了,为什么还要用jsonp跨域。这种跨域请求主要有哪些作用?
这篇文章讲的挺好的其实:看完就大概懂了,在这里推荐下。
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
都传送,我来简单说一下原理吧
论点:
jsonp和ajax没半毛钱关系
jsonp和json也没半毛钱关系
证明:
script:src 是不会跨域的,这是主要论据<script src="http://xxx.com/1.js"></script>
<script src="http://xxx.com/1.js"></script>
这个1.js的内容为:
1.js
var RESULT = {"data": .....};
这样加载之后,大家都可以获得RESULT这个变量,这个很容易理解。
那jQuery的ajax是如何请求并加载这个页面呢?
$.getScript('http://.../1.js', function(){ console.log(RESULT.data); }); 或 $.ajax({ url: 'http://.../1.js', dataType: 'script', success: function(){ console.log(RESULT.data); } }
看起来是用ajax请求的,其实是jQuery做了一个模拟,真实代码更像:
var s = document.createElement('script'); s.src = 'http://.../1.js'; s.onload = function(){ 通知jQuery.ajax,我已经加载完毕了 }
为什么会诞生jsonp?因为在当年,IE 6风行的时候,getScript(或ajax{dataType:'script'},下同),请求js资源是同步方式(因为浏览器请求jpg/css资源都是同步),也就是请求到一个之后,才会请求下一个,而当年网络上的ajax控件也大部分是做的同步(即使当年ajax支持异步,但是在IE 6下也无法将getScript变成异步,这是浏览器内核的问题)。
getScript
ajax{dataType:'script'}
--- 同步,的确满足楼主的要求,但是:会卡浏览器,会白屏。
所以:为了异步请求,Chrome诞生了,接着IE、firefox跟进都异步了。
但是异步会到导致一个问题:因为网络的原因,我根本不知道RESULT变量是谁传回来的,并且RESULT会被后请求到的数据覆盖。
所以聪明的前端工程师想到
calljQueryWhoAmI({"data": ....});
只要这个calljQueryWhoAmI是不停变化,我就知道是谁返回给我的
jsonp流程
用户发起jsonp请求
$.ajax({ url:'http://.../1.php?callback=?', dataType: 'jsonp', });
jquery开始做如下工作
这是第5次请求
生成一个callback的随机名字
var callback = 'callback_123456789';
绑定这个名字到用户请求的ajax的序号5
jqueryAjax[5] = callback;
替换用户的网址为
http://.../1.php?callback=callback_123456789
新建一个函数来接受数据
var callback_123456789 = function(json) { jQuerySuccess([5, json]); //回调第5个success }
开始请求数据
createElement('script').src="http://.../1.php?callback=callback_12345789";
用户收到http://.../1.php?callback=callback_123456789做的工作
<?php $callback = $_GET['callback']; $data = read database.... echo $callback.'('.json_encode($data).');'
也就是echo
callback_12345789({"data": ...})
当这个<script src="http://.../1.php?callback=callback_12345789"></script>加载完毕时,浏览器会自动去
<script src="http://.../1.php?callback=callback_12345789"></script>
call callback_12345789
流程继续到jQuery的
var callback_123456789 = function(json)
你通过success接受到数据,开始工作
success
这里是一个简单的逻辑,具体的实现会更加智能和科学一些,比如:闭包等方式,但是以上观点可以帮助你理解jsonp
为什么 jsonp 和json没任何关系:
根据浏览器的安全特性同域的任何文本,比如xml、html、jpg都可以被ajax请求到,其实都是当做文本来处理当然,json就是文本的一种然后javascript无缝支持 JSON.parse(文本)你就得到了json值,就这样
JSON.parse(文本)
而 jsonp更近似于 getscript 的处理方式,连JSON.parse都不用,所以,他们有什么关系?唯一的关系是:json == javascript's Object
getscript
JSON.parse
因为根据浏览器同源策略,a 域的js不能直接访问 b域名的信息,但是script 标签的src属性可以跨域引用文件,jsonp是请求之后后台包装好一段json,并且把数据放在一个callback函数,返回一个js文件,动态引入这个文件,下载完成js之后,会去调用这个callback,通过这样访问数据。
如果你请求出去,然后需要处理请求返回的结果,这个时候jsonp的用处就出来了,一个回调函数,里面有你需要处理的数据。
我来个传送么:为什么是 JSONP
同传送 http://www.cnblogs.com/zichi/...
JSONP全称是"JSON with Padding",个人理解就是"填充JSON"的意思.填充到哪里?就是填充到JS函数调用时的参数里.可见JSONP的本质就是带有JSON数据的JS函数调用,它是一句合法的JS代码.JSONP能通过AJAX跨域请求的原理(前提)是:浏览器不会拦截跨域输出的JS代码,就像<script>标签能跨域加载JS脚本那样.
下面以jQuery的$.ajax函数为例说明:
先用PHP开2个不同域的HTTP服务:
php -S 127.0.0.1:8080 -t /home/eechen/www1 php -S 127.0.0.2:8080 -t /home/eechen/www2
然后是 127.0.0.1:8080 AJAX跨域请求 127.0.0.2:8080 的JSONP数据.
http://127.0.0.2:8080/jsonp.php 内容:
http://127.0.0.2:8080/jsonp.php
<?php header('Content-Type: application/javascript'); //建议指定响应头为JS代码 echo $_GET['callback'].'('.json_encode(array('Server'=>'PHP')).')';
http://127.0.0.1:8080 通过AJAX发出JSONP请求:
http://127.0.0.1:8080
$.ajax({ type: "GET", //JSONP只能通过GET方式发出请求 url: "http://127.0.0.2:8080/jsonp.php", data: {name:"ele", pass:"123"}, dataType: "jsonp" // 发出的GET请求 http://127.0.0.2:8080/jsonp.php?callback=jQuery112400641287495426539_1477561917569&name=ele&pass=123&_=1477561917570 // 返回的JSONP数据 jQuery112400641287495426539_1477561917569({"Server":"PHP"}) }).done(function(data){ console.log(data); //data即为获取到的JSON对象 {"Server":"PHP"} });
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
这篇文章讲的挺好的其实:看完就大概懂了,在这里推荐下。
都传送,我来简单说一下原理吧
论点:
jsonp和ajax没半毛钱关系
jsonp和json也没半毛钱关系
证明:
script:src 是不会跨域的,这是主要论据
<script src="http://xxx.com/1.js"></script>这个
1.js的内容为:这样加载之后,大家都可以获得RESULT这个变量,这个很容易理解。
那jQuery的ajax是如何请求并加载这个页面呢?
看起来是用ajax请求的,其实是jQuery做了一个模拟,真实代码更像:
为什么会诞生jsonp?
因为在当年,IE 6风行的时候,
getScript(或ajax{dataType:'script'},下同),请求js资源是同步方式(因为浏览器请求jpg/css资源都是同步),也就是请求到一个之后,才会请求下一个,而当年网络上的ajax控件也大部分是做的同步(即使当年ajax支持异步,但是在IE 6下也无法将getScript变成异步,这是浏览器内核的问题)。---
同步,的确满足楼主的要求,但是:会卡浏览器,会白屏。
但是异步会到导致一个问题:因为网络的原因,我根本不知道RESULT变量是谁传回来的,并且RESULT会被后请求到的数据覆盖。
所以聪明的前端工程师想到
只要这个calljQueryWhoAmI是不停变化,我就知道是谁返回给我的
jsonp流程
用户发起jsonp请求
jquery开始做如下工作
这是第5次请求
生成一个callback的随机名字
绑定这个名字到用户请求的ajax的序号5
替换用户的网址为
新建一个函数来接受数据
开始请求数据
用户收到
http://.../1.php?callback=callback_123456789做的工作也就是echo
当这个
<script src="http://.../1.php?callback=callback_12345789"></script>加载完毕时,浏览器会自动去流程继续到jQuery的
你通过
success接受到数据,开始工作这里是一个简单的逻辑,具体的实现会更加智能和科学一些,比如:闭包等方式,但是以上观点可以帮助你理解jsonp
为什么 jsonp 和json没任何关系:
而 jsonp更近似于
getscript的处理方式,连JSON.parse都不用,所以,他们有什么关系?唯一的关系是:json == javascript's Object
因为根据浏览器同源策略,a 域的js不能直接访问 b域名的信息,但是script 标签的src属性可以跨域引用文件,jsonp是请求之后后台包装好一段json,并且把数据放在一个callback函数,返回一个js文件,动态引入这个文件,下载完成js之后,会去调用这个callback,通过这样访问数据。
如果你请求出去,然后需要处理请求返回的结果,这个时候jsonp的用处就出来了,一个回调函数,里面有你需要处理的数据。
我来个传送么:为什么是 JSONP
同传送 http://www.cnblogs.com/zichi/...
JSONP全称是"JSON with Padding",个人理解就是"填充JSON"的意思.
填充到哪里?就是填充到JS函数调用时的参数里.
可见JSONP的本质就是带有JSON数据的JS函数调用,它是一句合法的JS代码.
JSONP能通过AJAX跨域请求的原理(前提)是:
浏览器不会拦截跨域输出的JS代码,就像<script>标签能跨域加载JS脚本那样.
下面以jQuery的$.ajax函数为例说明:
先用PHP开2个不同域的HTTP服务:
然后是 127.0.0.1:8080 AJAX跨域请求 127.0.0.2:8080 的JSONP数据.
http://127.0.0.2:8080/jsonp.php内容:http://127.0.0.1:8080通过AJAX发出JSONP请求: