# 3.AJAX基本使用

# 3.1 AJAX请求的基本操作

<!-- index.html -->
<script>
    // 获取btn元素
	const btn = document.getElementsByTagName('button')[0];
    // 绑定事件
    btn.onclick = function () {
        // 测试点击事件
        console.log('btn is onclick')
    }
</script>

# 3.1.1 创建对象

new XMLHttpRequest()

btn.onclick = function(){
	// 1.创建对象
    const xhr = new XMLHttpRequest();
}

# 3.1.2 初始化 设置请求方法和url

xhr.open(方法, url)

btn.onclick = function(){
    const xhr = new XMLHttpRequest();
    // 2.初始化 设置请求方法和url
    // xhr.open(方法, url)
    xhr.open('GET', 'http://127.0.0.1:8000/server')
}

# 3.1.3 发送

xhr.send()

btn.onclick = function(){
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/server');
    // 3.发送
    xhr.send();
}

# 3.1.4 事件绑定 处理服务端返回的结果

btn.onclick = function(){
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/server');
    xhr.send();
    // 4.事件绑定 处理服务端返回的结果
    // on 当
    // readystate 是xhr对象中的属性,表示状态 0 1 2 3 4
    // change 改变
    xhr.onreadystatechange = function () {
        // 判断 服务端返回了所有的结果
        if(xhr.readyState === 4){
            // 判断响应状态状态码
            // 2xx 都是成功
            if(xhr.status >= 200 && xhr.status < 300) {
                // 处理结果 行 头 空行 体
                // 1.响应行
                console.log(xhr.status);	//响应状态码
                console.log(xhr.statusText);	//状态字符串
                console.log(xhr.getAllResponseHeaders());	//所有响应头
                console.log(xhr.response);	// 响应体
                // 设置result的文本
                result.innerHTML = xhr.response;
            } else {
                
            }
        }
    }
}

# 3.1.5 代码总结

const btn = document.getElementsByTagName('button')[0];
const result = document.getElementById('result');
btn.onclick = function(){
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/server');
    xhr.send();
    xhr.onreadystatechange = function () {
        if(xhr.readyState === 4){
            if(xhr.status >= 200 && xhr.status < 300) {
                result.innerHTML = xhr.response;
            }
        }
    }
}

# 3.1.6 get方法 设置请求参数

xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200&c=300')

# 3.2 发送POST请求

# 3.2.1 post方法

<!-- index2.html -->
<!-- 需求:鼠标光标进入div#result时,发送请求,接收数据并显示 -->
<style>
    #result{
        width:200px;
        height:200px;
        border: soild 1px black;
    }
</style>

<div id="result">
    
</div>

<script>
	// 获取元素对象
    const result = document.getElementById('result');
    // 绑定事件
    result.addEventListener('mouseouver', function(){
        // 创建对象
        const xhr = new XMLHttpRequest();
        // 初始化,设置类型与url
        xhr.open('POST', 'http://127.0.0.1:8000/server');
        // 发送
        xhr.send();
        // 事件绑定
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status >= 200 && xhr.status < 300) {
                    // 处理服务端返回的结果
                    result.innerHTML = xhr.response;
                }
            }
        }
    })
</script>

运行一下,会发现,报错了

Access to XMLHttpRequest at 'http://127.0.0.1:8000/server' from origin 'http://127.0.0.1:8848' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是因为,我们在 server.js 中 没有 POST 匹配的路由规则

我们在server.js中,添加对应的路由规则

app.post('/server', (request, response) => {
	// 设置响应头 设置允许跨域
	response.setHeader('Access-Control-Allow-Origin','*')
	
	// 设置响应体
	response.send('HELLO EXPRESS!')
})

重启服务。

# 3.2.2 post方法设置请求体

// index2.html
 result.addEventListener('mouseouver', function(){
    // 创建对象
    const xhr = new XMLHttpRequest();
    // 初始化,设置类型与url
    xhr.open('POST', 'http://127.0.0.1:8000/server');
    // 发送
  	// 在 post 方法中,参数是通过send()方法传递的
    // 可以传递任何形式的字符串
    xhr.send('a=100&b=200&c=300');
    // 事件绑定
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            if(xhr.status >= 200 && xhr.status < 300) {
                // 处理服务端返回的结果
                result.innerHTML = xhr.response;
            }
        }
    }
})

# 3.3 设置请求头信息

// server.js
response.setHeader('Access-Control-Allow-Origin','*');
// 接收所有头信息
response.setHeader('Access-Control-Allow-Header','*');
xhr.open('POST', 'http://127.0.0.1:8000/server');
// 在open方法之后,设置请求头
// xhr.setRequestHeader(头的参数,头的值)
xhr.setRequestHeader('Content-Type','Content-Type' , 'application/x-www-form-urlencoded');
xhr.setRequestHeader('name', 'zhangsan')// 不需要强记

# 3.4 服务端响应JSON数据

// server.js
app.all('/json-server', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin','*');
    const data = {
        label: '张三犯了什么罪!'
    };
    // 将对象转换 --> json
    let str = JSON.stringify(data);
    response.send(str);
})
// index3.html
// 手动设置
const btn = document.getElementById('btn');
const result = document.getElementById('result');
btn.onclick = function () {
	// 发送请求
    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://127.0.0.1:8000/json-server');
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if(xhr.status >= 200 && xhr.status <300) {
                // 手动转换
                // 将json转换回对象
                const data = JSON.parse(xhr.response);
                result.innerHTML = data.label;
            }
        }
    }
}
// index3.html
// 自动设置
btn.onclick = function () {
	// 发送请求
    const xhr = new XMLHttpRequest();
    // 自动设置,设置类型
    xhr.responseType = 'json';
    xhr.open('GET', 'http://127.0.0.1:8000/json-server');
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if(xhr.status >= 200 && xhr.status <300) {
                result.innerHTML = xhr.response.label;
            }
        }
    }
}

# 3.5 nodemon

nodemon的作用:重启服务

安装:

npm install -g nodemon

安装完成之后,启动服务不再使用 node server.js

// 不再使用 node server.js
nodemon server.js

修改server.js时会自动重启

# 3.6 IE缓存问题

在IE浏览器中,会对AJAX的请求结果进行缓存,下一次请求时会进行本地访问而不是访问服务器。

<!-- IEindex.html -->
<style>
    #result{
        width:200px;
        height:200px;
        border: 1px soild black;
    }
</style>


<button id="btn">按钮</button>
<div id="result"></div>

<script>
	const btn = document.querySelector('#btn');
    const result = document.querySelector('#result');
    
    btn.addEventListener('click', function(){
        const xhr = new XMLHttpReuqest();
        xhr.open('GET', 'http://127.0.0.1:8000/ie');
        xhr.send();
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4){
                if(xhr.status >= 200 && xhr.status<300){
                    result.innerHTML = xhr.response;
                }
            }
        }
    })
</script>

成功以后,我们修改服务端的内容,然后我们再点击按钮。

请注意,使用IE浏览器

会发现,IE没法更新新的内容

所以,我们需要做个修改

xhr.open('GET', 'http://127.0.0.1:8000/ie?t='+Date.now());
// 通过在后缀添加一个当前时间,就可以让每一次请求都作为一个新的请求,这样子就不会被缓存影响

# 3.7 请求超时与网络异常处理

在项目上线之后,用户发送的请求可能会因为各种原因而出现请求超时的情况

我们需要给请求添加一个超时处理

const xhr = new XMLHttpRequest();
// 超时设置
xhr.timeout = 2000;
xhr.ontimeout = function () {
    alert('网络异常,请稍后重试');
}
// 网络异常
xhr.onerror = function () {
    alert('您的网络似乎有点问题?请检查一下!')
}

# 3.8 取消请求

<button>发送</button>
<button>取消</button>

<script>
	const btns = document.querySelectorAll('button');
    let xml = null;
    btns[0].onclick = function () {
        xml = new XMLHttpRequest;
        xml.open('GET', 'http://127.0.0.1:800/delay');
        xml.send();
    }
    // abort() 取消
    btns[1].onclick = function () {
        xml.abort();
    }
</script>

# 3.9 请求重复发送的问题

每次触发请求发送事件都会创建一个请求,造成请求的重复发送,造成服务器压力过大。

// 通过标识变量 来判断是否正在发送AJAX请求
let isSending = false
btns[0].onclick = function () {
    if(isSending) { return }
	xml = new XMLHttpRequest;
     if(inSending == false)
     // ...
    
    xml.onreadystatechange = function(){
        if(x.readyState === 4) {
            isSending = false;
            // ...
        }
    }
}
更新时间: 6/29/2021, 4:20:37 PM