前端充电站--重新认识ajax、跨域、cors、jsonp

249 阅读3分钟

AJAX是异步的JavaScript和xml(数据传输格式)

//一个简易的ajax下载数据请求(基于'GET'请求)

1.创建ajax对象
var xhr=new XMLHttpRequest();

2.调用open方法
xhr.open('GET',url,true)

3.调用send方法
xhr.send(null);

4.等待数据响应并进行相应的验证
xhr.onreadystatechange=function(){
	if(xhr.readyState == 4){
    	if(xhr.status===200){
        	console.log(xhr.responseText)
        }
    }
}

/*
!!!第一步注意事项: 

XMLHttpRequest  IE8以下不兼容

兼容方式:
var xhr = null;
if(window.XMLHttpRequest){
	xhr = new XMLHttpRequest();
}else{
	xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
*/

/*
!!!第二步注意事项:

open()方法的参数
参数一:请求方式  'GET'、'POST'等
参数二:请求地址   
参数三:请求方式  true异步请求(默认)
*/

/*
!!!第三步注意事项:
'GET'请求方式只需xhr.send(null)

'POST'请求方式则不同
send(JSON.Stringify(data))方法需要发送json格式的字符串
*/

/*
!!!第四步注意事项:

xhr.readyState  发生变化的时候调用
0(未初始化)还没有调用send()方法
1(载入)已经调用send()方法正在发送请求
2(载入完成)send()方法执行完成 已经收到全部响应内容
3(交互)正在解析响应内容
4(完成)响应内容解析完成,可以在客户端调用

xhr.status 状态码   
2xx  表示成功处理请求
3xx  需要重定向,浏览器直接跳转
4xx  客户端请求错误
5xx  服务器端错误
*/
一个使用pomise封装的简易ajax请求(基于'GET'请求)

function ajax(url){
	return new Promise((resolve,reject)=>{
    	const xhr=new XMLHttpRequest();
        xhr.open('GET',url,true);
        xhr.ononreadystatechange=function(){
        	if(xhr.readyState === 4){
            	if(xhr.status===200){
					resolve(JSON.parse(xhr.responseText))
                }else{
                	reject(new Error('something wrong'))
            }
        }
        xhr.send(null)
    })
}

//使用方法
const url='url';
ajax(url)
.then(res=>{console.log(res)})
.catch(err=>{console.log(err)})

跨域

所有的跨域,都必须经过server端允许和配合 未经server端允许就可以实现跨域,说明浏览器有漏洞

同源策略 协议、端口、域名三者必须一致

ajax请求数据时,浏览器要求当前网页和server必须符合同源策略,否则请求数据失败。

加载图片、CSS、JS可无视同源策略

<img src='跨域的图片地址'/>

<link href='跨域的css地址'/>

<script src='跨域的js地址'></script>

cors(服务端支持) 服务器设置http header

//第二个参数填写允许跨域的域名称,不建议写*
response.setHeader('Access-Control-Allow-Origin','http://localhost:8080')
response.setHeader('Access-Control-Allow-Headers','X-Requested-With')
response.setHeader('Access-Control-Allow-Methods','PUT,POST,GET,DELETE,OPTIONS')

//接收跨域的cookie
response.setHeader('Access-Control-Allow-Credentials','true')

jsonp的实现利用了script标签的无视同源策略

JSONP跨域的使用流程:

1、先去声明一个函数,这个函数有一个形参,这个形参会拿到我们想要下载的数据,使用这个参数做后续数据的处理

2、在需要下载数据的时候,动态创建script标签,将标签src属性设置成下载数据的链接

3、当script插入到页面上的时候,就会调用已经封装好的函数,将我们需要的数据传过来。

<script>
window.onload = function(){
    var oBtn = document.getElementById("btn1");  //获取页面上的一个按钮
    oBtn.onclick = function(){  //给按钮添加点击事件
        var oScript = document.createElement("script");  //动态创建script标签
        oScript.src = 'demo.txt';    //将src属性设置成下载数据的链接
        document.body.appendChild(oScript);    //将script添加到页面上
    }
}
</script>

ajax静默提交

  • 模拟实现jquery的$.ajax()方法
// $.ajax({
//     url:'',  //必须方法
//     method:'get',
//     async:true, //布尔类型
//     data:{},  //
//     dataType,
//     success:function(){
//     }
// })


var $ = {
    ajax: function (options) {
        var xhr = null, // 为了创建XMLHttpRequest对象
            url = options.url, // url地址
            method = options.method || 'get', // 传输方式,默认为get
            async = typeof (options.async) === "undefined" ? true : options.async,
                data = options.data || null, // 参数
                params = '',
                callback = options.success, // ajax请求成功的回调函数                   
                error = options.error;
        // 将data的对象字面量的形式转换为字符串形式
        if (data) {
            for (var i in data) {
                params += i + '=' + data[i] + '&';
            }
            //这里的结尾多了一个&
            params = params.replace(/&$/, "");
        }
        // 根据method的值改变url
        if (method === "get") {
            url += '?' + params; //需要把params拼接在url后面
        }
        if (typeof XMLHttpRequest != "undefined") {
            xhr = new XMLHttpRequest();
        } else if (typeof ActiveXObject != "undefined") {
            // 将所有可能出现的ActiveXObject版本放在一个数组中
            var xhrArr = ['Microsoft.XMLHTTP', 'MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP.2.0'];
            // 遍历创建XMLHttpRequest对象
            var len = xhrArr.length;
            for (var i = 0; i < len; i++) {
                try {
                    // 创建XMLHttpRequest对象
                    xhr = new ActiveXObject(xhrArr[i]);
                    break;
                } catch (ex) {

                }
            }
        } else {
            throw new Error('No XHR object availabel.');
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
                    callback && callback(JSON.parse(xhr.responseText))
                } else {
                    error && error();
                }
            }
        }
        // 创建发送请求
        xhr.open(method, url, async);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(params);
    }
}