关于JSONP - 读Head First HTML5 Programming 第六章
第六章上半部分讲XMLHttpRequest有关内容,由于不能做跨域请求,引出下半章JSONP。
本章知识点:
1. XMLHttpRequest
我用node 在本地起了两个服务
端口号一个为80 ,一个为90。
ps: 浏览器判断是否跨域的标准:域名 端口号 (ie不判断端口号)
<body>
T1 TEST
<div id="wrapper"></div>
<script>
window.onload = function () {
var url = 'http://127.0.0.1:90/t2.json';
var request = new XMLHttpRequest();
request.onload = function(){
if (request.status == 200) {
displayResponse(request.responseText);
}
}
request.open('GET', url);
request.send(null);
}
function displayResponse(txt){
var wrapper = document.getElementById('wrapper');
wrapper.innerHTML = txt;
}
</script>
</body>
此时出现跨域问题(如果url=t1.json 就没有此问题)
2. 浏览器安全策略 同源策略
用户可以通过浏览器发出html css js img 等请求,但是页面使用XMLHttpRequest 发出请求时,浏览器看到这个指向与页面不同域,就会停下来,请求被拒绝。也就是在浏览器端就被拦截了,这个请求就没有发出去。
3. JSONP (JSON with Padding)
(function() {
t1();
})();
t2加入一个js文件 调用t1文件下的js
t1文件 如下
<script>
window.onload = function () {
var url = 'http://127.0.0.1:90/t2.json';
var request = new XMLHttpRequest();
request.onload = function(){
if (request.status == 200) {
displayResponse(request.responseText);
}
}
request.open('GET', url);
request.send(null);
}
function displayResponse(txt){
var wrapper = document.getElementById('wrapper');
wrapper.innerHTML = txt;
}
function t1(){
alert('t1中的函数 但没有执行 t2js可以执行');
}
</script>
<script src="http://127.0.0.1:90/t2.js"></script>
此时alert执行,由此引出jsonp思路。 我们可以通过引用的js进行数据传递。
进入正题
首先要注意3个问题
1.web服务器允许增加一个回调函数 callback=fn 获取正确的函数名
2.为保证数据实时更新 加一个定时器更新js引入(只更新src js不会重新加载)
3.防止浏览器缓存要加时间戳
ok,将t1.html 改为
<body>
T1 TEST
<div id="wrapper"></div>
<script>
window.onload = function () {
setInterval(refresh, 3000);
}
function displayResponse(obj){
var wrapper = document.getElementById('wrapper');
var div = document.createElement('div');
div.innerHTML = 'name:' + obj.name + '; age:' + obj.age + '; gender:' + obj.gender + '; pet:' + obj.pet;
wrapper.appendChild(div);
}
function refresh(){
var url = 'http://127.0.0.1:90/t2.js?callback=displayResponse' + '&random=' + (+new Date());
var newJs = document.createElement('script');
newJs.setAttribute('src', url);
newJs.setAttribute('id', 'jsonp');
var oldJs = document.getElementById('jsonp');
var head = document.getElementsByTagName('head')[0];
if (oldJs == null) { //注意 这块判断用 null
head.appendChild(newJs);
}else{
head.replaceChild(newJs, oldJs);
}
}
</script>
</body>
t2.js 模拟服务器提供数据
(function() {
var obj = {
"name": "cotton2",
"age": "2",
"gender": "male2",
"pet": "dog2"
};
displayResponse(obj);
})();
结果成功啦
ps : 用XMLHttpRequest请求来的数据 是json字符串 因此下面记住两个方法
字符串转对象 var jsonObj = JSON.parse(jsonString);
对象转字符串 var jsonString = JSON.stringify(jsonObj);