JSONP
JSONP 是JSON with padding(填充式JSON 或参数式JSON)的简写;JSONP 看起来与JSON 差不多,只不过是被包含在函数调用中的JSON,就像这样:
callback({ "name": "li" });
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调
函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据。举例:
<script>http://api.jirengu.com/city.php?callback=getCity</script>
jsonp实例:
html代码
<p>您现在所听的歌曲为:</p>
<p id="songs"></p>
<br>
<p id="singer"></p>
<img src="" id="songImg">
js代码
var songs= document.getElementById('songs');
var singer= document.getElementById('singer');
var songImg= document.getElementById('songImg');
function getSong(res) {
var song = res.song[0];
songs.innerHTML=song.title;
singer.innerHTML = song.artist;
songImg.src=song.picture;
}
var script = document.createElement('script');
script.src="http://api.jirengu.com/fm/getSong.php?channel=4&callback=getSong";
document.head.appendChild(script);
CORS
CORS全局资源共享, 整个CORS通信过程,都是浏览器自动完成,不需要用户参与,对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
实现CORS的关键在于服务器,只要服务器开启了CORS接口,就可以实现跨域。
浏览器将CORS请求分为两部分简单请求和非简单请求
只要同时满足下面两大条件就属于简单请求。
请求方法是:get,post,head之一;
HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
其他的请求则被称为非简单请求。
简单请求:浏览器直接发出CORS请求。在头信息中增加一个Original字段,标明本次请求来自哪个源。服务器根据值来决定是否同意这次请求。
如果不在允许范围内,服务器也会返回一个正常响应,但浏览器发现这个回应的头信息没有包含Access-Control-Allow-Origin字段,浏览器便会抛出一个错误;
如果在允许范围内,服务器返回的响应会多几个头信息字段。
<!doctype html>
<html>
<meta charset="UTF-8">
<head>
</head>
<body>
<div class="query-area">
<input type="text" name="username" value="hunger" placeholder="hunger, ruoyu, anyone">
<button>查询朋友</button>
</div>
<div class="detail-area">
<ul>
</ul>
</div>
<script>
var btn = document.querySelector('.query-area button')
var input = document.querySelector('.query-area input')
btn.addEventListener('click', function(){
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)){
var friends = JSON.parse(xhr.responseText)
render(friends)
}
}
xhr.open('get', 'http://localhost:8080/getFriends?username=' + input.value, true)
xhr.send()
})
function render(friends){
var detailCt = document.querySelector('.detail-area ul')
detailCt.innerHTML = '';
var ct = document.createDocumentFragment()
for(var i = 0; i < friends.length; i++){
var node = document.createElement('li')
node.innerText = friends[i]
ct.appendChild(node)
}
detailCt.appendChild(ct)
}
</script>
</body>
</html>
服务器端代码:
router.get('/getFriends', function(req, res) {
var username = req.query.username // 通过 req.query获取请求参数
var friends
//根据请求参数mock数据
switch (username){
case 'ruoyu':
friends = ['小米', '小刚']
break
case 'hunger':
friends = ['小谷', '小花']
break;
default:
friends = ['没有朋友']
}
res.header("Access-Control-Allow-Origin","*");
res.send(friends)
})
没加res.header("Access-Control-Allow-Origin","*");跨域失败
加了之后成功获取数据
postMessage
postMessage主要用于解决页面与打开新窗口的数据传递;
多窗口之间的消息传递;
页面和嵌套的iframe消息传递。
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
postMessage(data,origin)方法接收两个参数:
1.data:要传递的数据;html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化
2.origin:字符串,指明目标窗口的源,协议+主机+端口号[+URL]
//a.html
<!doctype html>
<html>
<meta charset="UTF-8">
<head>
<style>
.ct{
width: 910px;
margin: auto;
}
.main{
float: left;
width: 450px;
height: 300px;
border: 1px solid #ccc;
}
.main input{
margin: 20px;
width: 200px;
}
.iframe{
float: right;
}
iframe{
width: 450px;
height: 300px;
border: 1px dashed #ccc;
}
</style>
</head>
<body>
<div class="ct">
<h1>使用postMessage实现跨域</h1>
<div class="main">
<input type="text" placeholder="http://localhost:8080/a.html">
</div>
<iframe src="http://localhost:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
$('.main input').addEventListener('input', function(){
window.frames[0].postMessage(this.value,'*');
})
window.addEventListener('message',function(e) {
$('.main input').value = e.data
});
function $(id){
return document.querySelector(id);
}
</script>
</body>
</html>
//b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
html,body{
margin: 0;
}
input{
margin: 20px;
width: 200px;
}
</style>
</head>
<body>
<input id="input" type="text" placeholder="http://localhost:63342/server-mock/b.html">
<script>
$('#input').addEventListener('input', function(){
window.parent.postMessage(this.value, '*');
})
window.addEventListener('message',function(e) {
$('#input').value = e.data
});
function $(id){
return document.querySelector(id);
}
</script>
</body>
</html>