ajax与jsonp的原理
发送网络请求的几种方式:
1、在浏览器中输入网址(代码无法控制);
2、location.href = ‘http://www.xxx.com’,可以发出网络请求,页面会发生跳转;(页面跳转)
3、带有src和带有href属性的标签,也能发出请求,并且服务端也会处理并返回,但是返回的结果能否被应用,还要看浏览器;(页面无法处理返回结果)
4、带有action属性的标签,例如form表单也可以向后端发出请求,但form表单发出的请求,也会发生页面跳转;(页面跳转)
针对以上情况,当前急需一种能够用代码控制,页面不会发生跳转,服务端返回的结果是可以用js代码继续处理,
操作dom实现局部刷新,ajax应运而生。
同源策略:协议、域名、端口号一致。
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHttp"); //IE6
}
console.log(xhr.readyState); // 0
xhr.open('GET','https://developer.duyiedu.com/edu/testAjaxCrossOrigin',true);
console.log(xhr.readyState); // 1
xhr.onreadystatechange = function(){
//readyState == 4 表示请求完成,已经接收到数据
// status == 200 网络请求,结果都会有一个状态码。来表示这个请求是否正常
// 200 表示请求成功
// http 状态码
// 2** 表示成功
// 3** 表示重定向
// 4** 表示客户端错误,404页面没找到
// 5** 服务端错误
// console.log(xhr.readyState,xhr.status)
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
}
console.log(xhr.readyState); // 1
xhr.send();// 如果open第三个参数传true,或者不传,为异步模式,如果传false,为同步模式
console.log(xhr.readyState); //异步 1 同步 4
console.log('=====')
post请求与get请求写法上的区别:
xhr.open("POSt", "./getInput.php", true)
// 如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。
//然后在 send() 方法中规定您希望发送的数据
xhr.setRequestHeader("content-type", "application/x-www-form-urlcoded");
xhr.send("name=amiee&age=18");
ajax是受同源策略的限制的。
JSONP的原理:
1、判断请求的域与当前页面的域是否同源,如果同源则正常发送ajax,就没有跨域的事了;
2、如果不同源,会生成一个script标签;
3、生成一个随机的callback名字,还得创建一个名为这个的方法;
4、设置script标签的src,设置为要请求的接口;
5、将callback作为参数拼接在后面;
=以上为前端部分==
6、后端接收到请求后,开始准备要返回的数据;
7、后端拼接数据,将要返回的数据用callback的值和括号包裹起来;
例如:callback= asd23456,要返回的额数据为{a:1,b:2};
就要拼接为asd23456({a:1,b:2});
8、将内容返回
=以上是后端部分==
9、浏览器接收到内容,会当做js代码来执行;
10、从而执行名为asd23456的方法,这样我们就接收到后端返回给我们的对象了。
jsonp的封装:
var $ = {
ajax:function(options){
var url = options.url;
var type = options.type;
var dataType = options.dataType;
//判断是否同源
//获取目标url的域
var targetProtocol = '' ;//目标接口的协议;
var targetHost = ''; //目标接口的host,host是包含域名和端口的
//如果url不戴http,那么访问的一定是相对路径,相对路径一定是同源的
if(url.indexOf('http://') == 0 || url.indexOf('https://') == 0){
var targetUrl = new URL(url);
targetProtocol = targetUrl.protocol;
targetHost = targetUrl.host;
}else{
targetProtocol = location.protocol;
targetHost = location.host;
}
//判断是否为jsonp,因为不是jsonp,就不用做其他的判断,直接发送ajax
if(dataType === 'jsonp'){
if(location.protocol == targetProtocol && location.host == targetHost){
//同源,正常ajax请求
//---------- 此处省略-------
}else{
//不同源
// 随机生成一个callback
var callback = 'cb' + Math.floor(Math.random()*100000000);
//给window上添加一个方法
window[callback] = options.success;
console.log(window[callback]);
//生成script标签
var script = document.createElement('script');
if(url.indexOf('?') > 0){ //表示有参数
script.src = url + '&cb='+callback;
}else{//表示无参数
script.src = url + '?cbsuo='+callback;
}
script.id = callback;
document.head.appendChild(script);
script.remove();
}
}
}
}