6.30 ajax 兼容性问题以及封装

ajax

1. AJAX在IE中的问题

1.1. XMLHttpRequest 对象IE兼容问题

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。

var xhr;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xhr=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
  }
1.2. AJAX在IE中的缓存问题

在默认情况下,IE会缓存相同地址ajax请求的结果。IE的第一次ajax请求会发送到服务器端处理,如果后续的请求的参数与第一次的一样,浏览器会直接返回缓存的结果而不是去服务器获取。有时候我们希望获取实时的数据,那么该如何解决这个问题呢?只要在ajax请求中加一个时间戳参数或随机参数就可以了。

console.log(Math.random());
console.log(new Date().getTime());
xhr.open('GET', './demo.txt?t=' + (new Date().getTime()), true)

2. 封装AJAX的GET请求

昨天我们学习了ajax的GET请求和POST请求,我们发现要实现一个ajax请求有五步操作,如果我们频繁的需要发送ajax请求,那么需要重复的去写着五步操作,显得很冗余,那么我们可不可以尝试着自己封装一下ajax的GET请求.

2.1. AJAX请求的五步操作:
// 1.创建一个异步对象
var xhr = new XMLHttpRequest()
// 2.(为异步对象)设置请求方式和请求地址
// open(method, url, async) async:true(异步) ajax 的意义就是异步,永远传true
xhr.open('GET', 'http://127.0.0.1:3030', true)
// 3.发送请求
xhr.send();
// 4.监听状态变化(调用回调函数代表请求完成了)
xhr.onreadystatechange = function () {
    // xhr.readyState判断请求是否完成
    if (xhr.readyState === 4) {
        // xhr.status判断是否拿到了数据
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            // 5.处理返回的结果
            console.log(xhr.response); 
        } else {
            console.log('没有接收到服务器的数据');
        }
    }
}
2.2. 处理参数问题

通过观察我们可以发现,如果我们要发送多个请求,这五步的大部分代码我们是不会改变的,需要改变的有

1.URL,请求地址是不固定的

2.GET请求传递的参数是不固定的

3.请求成功后如何处理数据,

4.请求失败后如何处理这三块需要变动

还需要解决的问题有IE浏览器的兼容问题

2.3. 处理IE兼容问题

根据以上问题:我们可以把不固定的内容用参数的方式传入,IE浏览器的兼容问题直接复制在里面即可

function obj_str(obj) { 
    obj.t = new Date().getTime()
    var res = []
    // { 'user_name': 'hello', 'user_password': 123 }
    for(var key in obj){
        res.push(key+'='+obj[key]) //[user_name=hello, user_password=123]
    }
    // join()方法把数组转换为字符串,用&符号隔开
    return res.join('&') //user_name=hello&user_password=123
 }

function my_ajax(url,obj,success,error){
    // 将传过来的obj对象转换为字符串
    var str = obj_str(obj)
    var xhr
    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xhr = new XMLHttpRequest()
    }
    else {// code for IE6, IE5
        xhr = new ActiveXObject("Microsoft.XMLHTTP")
    }
    // var timer = new Date().getTime()
    // xhr.open('GET', `${url}&&t=${timer}`, true)
    xhr.open('GET', `${url}?${str}`, true)
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                success(xhr)
            } else {
                error(xhr)
            }
        }
    }
}

调用页面

<script src="./js/my_ajax.js"></script>
<script>
    document.getElementsByClassName('btn1')[0].onclick = function () {
        my_ajax('http://127.0.0.1:3030', { 'user_name': 'hello', 'user_password': 123 }, 							function (xhr) {
            console.log(xhr.responseText);
        }, function (xhr) {
            console.log('请求失败');
        })
    }
</script>

优化:还需要去添加一个请求等待时间的功能,利用我们自己封装的ajax方法请求时,设置一个等待时间,如果在这个时间内没有响应我们的请求,那么我们就自己中断这次请求

在调用my_ajax()方法时传入一个时间参数,如3000毫秒

//调用页面
my_ajax('http://127.0.0.1:3030', { 'user_name': 'hello', 'user_password': 123 }, 3000, seccess(),error()		

然后在my_ajax()中用行参timeout接收

//my_ajax.js页面
function my_ajax(url,obj,timeout,success,error){
    ......
    //判断外界是否传入了超时时间
    if(timeout){
        timer = setInterval(function () { 
            // abort()方法用于中断请求
            console.log('中断请求');
            xhr.abort()
            clearInterval(timer)
         },timeout)
    }
}
4. 细节处理
4.1 超时问题

再严谨一点其实当我们判断请求如果完成了就应该把定时器清除掉,因为已经得到了服务器响应,如果此时因为超时而终止请求则中断请求就没有意义了

if (xhr.readyState === 4){
  clearInterval(timer)
  ......
}
4.2 url中文问题

在发送请求的过程中,URL中是不能出现中文的,在obj_str()函数中用encodeURIComponent()方法做处理

URL可以出现:字母/数字/下划线/ASCII码

res.push(encodeURIComponent(key)+'='+encodeURIComponent(obj[key]))
  1. 封装

3.封装AJAX的POST请求

POST请求的五步操作,基本和GET请求一致

<script>
    document.getElementsByClassName('btn1')[0].onclick = function () {
        var xhr
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xhr = new XMLHttpRequest()
        }
        else {// code for IE6, IE5
            xhr = new ActiveXObject("Microsoft.XMLHTTP")
        }
        console.log(xhr);
        xhr.open('POST', 'http://127.0.0.1:3030', true) //方法改为POST
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                    console.log(xhr.response)
                } else {
                    console.log('没有接收到服务器的数据')
                }
            }
        }
    }
</script>
3.1.POST请求如何传参

GET请求的参数放在URL里面,POST请求的参数放在请求头中

如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:

xhr.open('POST', 'http://127.0.0.1:3030', true)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send('user_name=bill&user_password=123');
3.2.封装POST请求

和GET请求基本一致,我们直接在封装好的GET请求里面做修改

2.1添加传过来的请求方式参数

2.2对传过来的type值做判断,如果是GET请求则用GET,POST请求则用POST请求方法

function my_ajax(type,url,obj,timeout,success,error){
  ......
  if(type === 'GET'){
        xhr.open(type, `${url}?${str}`, true)
        xhr.send();
    }else{
        xhr.open(type, url, true)
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(str);
    }
  ......
}

4. jQuery中的ajax

Jq很好的封装了原生的ajax,我们不需要直接创建xmlhttprequest

$.get(url, data, fn, dataType)

$.post(url, data, fn, dataType)

$.ajax()

4.1语法
$.ajax({
    name:value, 
    name:value, 
    ... 
})
2.1、语法:
$.ajax({
    name:value, 
    name:value, 
    ... 
})
配置项名称描述
beforeSend(xhr)发送请求前运行的函数。
async布尔值,表示请求是否异步处理。默认是 true。
cache布尔值,表示浏览器是否缓存被请求页面。默认是 true。
contentType发送数据到服务器时所使用的内容类型。默认是:“application/x-www-form-urlencoded”。
data规定要发送到服务器的数据。
dataType预期的服务器响应的数据类型。它可以指定为html json jsonp script text
dataFilter(data,type)用于处理 XMLHttpRequest 原始响应数据的函数。
error(xhr,status,error)如果请求失败要运行的函数。
success(result,status,xhr)当请求成功时运行的函数。
timeout设置本地的请求超时时间(以毫秒计)。
type规定请求的类型(GET 或 POST)。
url规定发送请求的 URL。默认是当前页面。

实例

  $('.btn3').click(function () {
            console.log('ajax');
            $.ajax({
                // url 给谁发请求
                url: 'http://127.0.0.1:3030',
                // 发送参数
                data: { user_name: 100, user_password: 200 },
                // 请求类型
                type: 'GET',
                //响应体结果
                dataType: 'json',
                // 请求成功的回调
                success: function (res) {
                    console.log(res);
                },
                // 超时时间
                timeout: 2000,
                error: function () {
                    console.log('出错了');
                },
                headers: {
                    a: 80,
                    b: 90
                },
            })
        })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值