1、什么是同源策略及限制
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
Cookie、LocalStorage和IndexDB无法读取
DOM无法获得
AJAX无法发送
2、前后端如何通讯
AJAX:同源策略
WebSocket:不受同源限制
CORS:都支持
3、如何创建AJAX
考察要点:
XMLHttpRequest对象的工作流程
兼容性处理
事件的触发条件
事件的触发顺序
创建步骤:
1、创建XMLHttpRequest对象
var request = new XMLHttpRequest();
2、设置请求参数
request.open("get", "http://10.0.152.17/AJAX/ajaxtest", true);
3、设置响应函数
request.onreadystatechange = function(){
if(request.readyState == 4) {
alert(request.responseText);
}
}
4、发送请求
request.send(string);
5、接收响应
request.responseText或者request.responseXML
//AjAX的请求封装
function ajax(method,url,params,done){
//统一转换为大写便于后续判断
method =method.toUpperCase();
//对象形式的参数转换为urlencoded格式
var pairs=[];
for(var key in params){
paies.push(key+'='+params[key])
}
var querystring=pairs.join('&');
var xhr=window.XMLHttpRequest ? new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
xhr.addEventListener('readystatechange',function(){
if(this.readyState!==4) return;
//尝试通过JSON格式解析响应体
try{
done(JSON.parse(this.responseText))
}catch(e){
done(this.responseText)
}
})
//如果是GET请求就设置URL地址问号参数
if(method==='GET'){
url+='?'+querystring;
}
xhr.open(method,url);
//如果是POST请求就设置请求体
var data=null;
if(method==='POST'){
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
data=querystring;
}
xhr.send(data);
}
ajax('get','./get.php',{id:123},function(data){
console.log(data)
})
ajax('post','./post.php',{foo:'posted data'},function(data){
console.log(data);
})
4、跨域通信的几种方式
1、JSONP
//html页面常用来实现的代码:
function jsonp (url, params, callback) {
var funcName = 'jsonp_' + Date.now() + Math.random().toString().substr(2, 5)
if (typeof params === 'object') {
var tempArr = []
for (var key in params) {
var value = params[key]
tempArr.push(key + '=' + value)
}
params = tempArr.join('&')
}
var script = document.createElement('script')
script.src = url + '?' + params + '&callback=' + funcName
document.body.appendChild(script)
window[funcName] = function (data) {
callback(data)
delete window[funcName]
document.body.removeChild(script)
}
}
jsonp('http://localhost/jsonp/server.php', { id: 123 }, function (res) {
console.log(res)
})
2、Hash
Hash:是url地址中#后面的部分,Hash改变页面不刷新。Search:是url地址中?后的部分,改变页面会刷新
// 利用hash,场景是当前页面 A 通过iframe或frame嵌入了跨域的页面 B
// 在A中伪代码如下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'data';
// 在B中的伪代码如下
window.onhashchange = function () {
var data = window.location.hash;
};
3、postMassage
// postMessage
// 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
Bwindow.postMessage('data', 'http://B.com');
// 在窗口B中监听
Awindow.addEventListener('message', function (event) {
console.log(event.origin);
console.log(event.source);
console.log(event.data);
}, false);
4、WebSocket
WebSocket,即浏览器与web服务器之间全双工通信标准。一旦web服务器与客户端建立了WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议执行。通信过程中,可互相发送JSON、XML、HTML或图片等任意格式的数据。
主要特点:1、推送功能。支持由服务器向客户端推送数据的推送功能。这样服务器可直接发送数据,而不必等待客户端的请求 2、减少通信量。只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减小了。
// Websocket【参考资料】http://www.ruanyifeng.com/blog/2017/05/websocket.html
var ws = new WebSocket('wss://echo.websocket.org');
ws.onopen = function (evt) {
console.log('Connection open ...');
ws.send('Hello WebSockets!');
};
ws.onmessage = function (evt) {
console.log('Received Message: ', evt.data);
ws.close();
};
ws.onclose = function (evt) {
console.log('Connection closed.');
};
5、CORS
fetch就是用来实现CORS通信的
// CORS【参考资料】http://www.ruanyifeng.com/blog/2016/04/cors.html
// url(必选),options(可选)
fetch('/some/url/', {
method: 'get',
}).then(function (response) {
}).catch(function (err) {
// 出错了,等价于 then 的第二个参数,但这样更好用更直观
});
// 一行代码搞定
// 允许跨域请求
header('Access-Control-Allow-Origin: *');
CORS为什么能支持跨域通信:如果请求是跨域的,浏览器会拦截AJAX请求,它会在HTTP头部中加Origin。