Ajax
原生Ajax
Ajax 全称为Asynchronous Javascript And XML,就是异步的 JS 和 XML。
通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势:页面无刷新获取数据。
Ajax 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
XML
- 可扩展标记语言。
 - XML 被设计用来传输和存储数据。
 - XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
 - 现在已经被JSON取代了。
 
Ajax特点
- 可以无需刷新页面而与服务器端进行通信
 - 允许你根据用户事件来更新部分页面内容
 
Ajax缺点
- 没有浏览历史,不能回退
 - 存在跨域问题
 - SEO不友好
 
核心对象 XMLHttpRequest
使用
<button id="btn">点我发送请求</button>
<div id="content"></div>
<script>
    const btn = document.getElementById('btn');
    const content = document.getElementById('content');
    btn.onclick = () => {
        //实例xhr
        const xhr = new XMLHttpRequest();
        //绑定监听
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    const {name, age, sex} = xhr.response;
                    content.innerHTML = (`
                        <ul>
                            <li>姓名:${name}</li>
                            <li>年龄:${age}</li>
                            <li>性别:${sex}</li>
                        </ul>
                    `);
                }
            }
        }
        //配置请求
        xhr.open('GET', 'http://127.0.0.1:8080/get_person')
        //responseType 用于指定返回数据的格式
        xhr.responseType = 'json';
        //发送请求
        xhr.send();
    };
</script>
//配置出错的回调
xhr.onerror = () => {
    alert('当前网络不稳定,请稍后重试');
}
//超时时间
xhr.timeout = 2000;
//超时的回调
xhr.ontimeout = () => {
    alert('网速不给力,请切换网络重试');
}
Ajax请求状态
xhr.readyState 可以用来查看请求当前的状态
- 0: 表示XMLHttpRequest实例已经生成,但open未调用。
 - 1: open已调用,但send还未调用,此时仍然可以修改请求头信息。
 - 2: 表示send()方法已经执行,并且头信息和状态码已经收到。
 - 3: 表示正在接收服务器传来的部分数据,小的数据会在此阶段一次性接收完毕,较大的数据有待进一步接收,响应头已经回来了
 - 4:表示数据已经接收完毕
 
IE-GET缓存问题
问题:在一些浏览器中(IE),由于缓存机制的存在,ajax只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:浏览器的ajax缓存是根据url地址来记录的,所以我们只需要修改url地址即可避免缓存问题。
xhr.open('GET', 'http://127.0.0.1:8080/get_person?t=' + Date.now())
Ajax 跨域
跨域问题:原因是浏览器为了安全,而采用的同源策略(Same origin policy)
同源策略
同源策略是由Netscape提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。 Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
所谓同源是指:协议,域名(IP),端口必须要完全相同。即:协议、域名(IP)、端口都相同,才能算是在同一个域里。
非同源受到的限制:
- Cookie不能读取;
 - DOM无法获得;
 - Ajax请求不能获取数据
 
如何解决跨域问题
JSONP解决发送请求跨域问题
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。 JSONP不是一种技术,而是程序员“智慧的结晶”(利用了标签请求资源不受同源策略限制的特点)
<body>
    <button id="btn">按钮</button>
    <script>
        const btn = document.getElementById('btn');
        btn.onclick = () => {
            //1.创建script节点
            const scriptNode = document.createElement('script');
            //2.给节点指定src属性(请求地址)
            scriptNode.src = 'http://127.0.0.1:8080/test_jsonp?callback=test';
            //3.将节点放入页面
            document.body.appendChild(scriptNode);
            //4.准备好一个函数
            window.test = (a) => {
                console.log(a);
            }
            //5.移除已经使用过的script节点
            document.body.removeChild(scriptNode);
        }
    </script>
</body>
app.get('/jsonp', (req, res) => {
    //解构赋值获取请求参数
    const {callback} = req.query
    //去数据库查找对应数据
    const data = [{name: 'tom', age: 18}, {name: 'jerry', age: 20}];
    res.send(callback + '(' + JSON.stringify(data) + ')');
})
后台配置cors解决跨域
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案, 它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持所有常见的请求。
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
// 以Node为例:
res.set('Access-Control-Allow-Origin', 'http://localhost:63342');
使用脚手架代理服务器
例如:React脚手架、Vue脚手架