AJAX()

一、简介

ajax用于向服务端发送异步请求,服务端返回结果。

其最大的特征就是在不刷新页面的情况下,更新页面内容。

        例如:你向下滚动页面,滚到底刷新新内容,就是等你翻到底部的时候,再向服务端发送请求,然后把数据插入页面。

1、XML可扩展标记语言(以前ajax返回的数据都是XML格式的,不过现在都是JSON格式了)

XML被设计用于传输和存储数据的。

XML和HTML类似,不同的是HTML都是预定义标签(预定义标签就是标签被提前定义好的),而XML中没有预定义标签,全部都是自定义标签,用来表示一些数据的

2、ajax

(1)优点

可以无需刷新页面而与服务器端进行通信

允许你根据用户事件来更新部分页面内容

(2)缺点

没有浏览历史,不能回退

存在跨域问题

SEO不友好(因为是动态发送请求获取数据,所以对爬虫不是特别友好,爬不到数据)

3.HTTP协议

hypertext transport protocal 超文本传输协议。

详细规定了浏览器和万维网之间互相通信的规则。

请求报文与响应报文:http://t.csdn.cn/0jUI8

二、ajax使用

1、安装express框架:

因为你要向服务端发送请求,就要有服务端,这里选择使用express创建服务端。

npm init --yes

npm i express

会生成一个package.json文件

2、ajax的get请求的基本操作

配置并启动express服务器

启动express服务器: 使用 node 加文件名,如node ajaxStudy/text7.js

但由于每次修改text7.js文件的内容都要重新启动一次,所以在终端输入npm install -g nodemon

再输入 nodemon 文件名,以后每一次修改text7.js文件会自动重新启动

(1)配置服务器并发送get请求

//1.引入express
// const { response } = require('express');
// const { request } = require('express');
const express = require('express');

//2.创建应用对象
const app = express();

//3.创建路由规则
app.get('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send('HELLO Ajax');
});

//4.监听端口服务
app.listen(8000,()=>{
    console.log("服务器已启动...");
})

ajax发送get请求


    <style>
        .result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>

<body>
    <button>点击发送请求</button>
    <div class="result"></div>

    <script>

        // 获取button元素
        const btn = document.getElementsByTagName('button')[0];
        //绑定事件
        btn.onclick = function(){
            //1.创建对象
            const xhr = new XMLHttpRequest();
            // 2.初始化 设置请求方法 和 url,即向url对应的地址发送什么样的请求
            xhr.open('GET','http://127.0.0.1:8000/server');
            //3.发送
            xhr.send();
            // 4.事件绑定  处理服务端返回的结果
            // on 当...的时候   
            //readystate 是xhr对象中的属性,表示状态0(表示初始状态) 1(表示open方法已经调用完毕) 2(表示send方法已经调用完毕) 3(表示服务端已经返回部分结果) 4(表示服务端返回了所有的结果)
            //change 改变
            // 这个方法改一次触发一次
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){//结果为true,表示返回了所有结果
                    // 判断响应状态码 200 404 403 401 500,2开头的数字都表示成功
                    if(xhr.status >=200 && xhr.status<300){
                        // 处理结果
                        console.log(xhr.status);//状态码
                        console.log(xhr.statusText);//状态字符串
                        console.log(xhr.getAllResponseHeaders);//所有响应头
                        console.log(xhr.response);//响应体
                    }else{

                    }
                }
            }
        }
    </script>
    
</body>
</html>

(2)、配置服务器并发送post请求

//1.引入express
// const { response } = require('express');
// const { request } = require('express');
const express = require('express');

//2.创建应用对象
const app = express();

//3.创建路由规则
//get规则
app.get('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send('HELLO Ajax GET');
});
//post规则
app.all('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*');

    // 设置响应体
    response.send('HELLO Ajax POST');
});

//4.监听端口服务
app.listen(8000,()=>{
    console.log("服务器已启动...");
})

 

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>
<body>
    <button>点击发送post请求</button>
    <div id="result"></div>

    <script>
        // 获取button元素
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        //绑定事件
        btn.onclick = function(){
            //1.创建对象
            const xhr = new XMLHttpRequest();
            // 2.初始化 设置请求方法 和 url,即向url对应的地址发送什么样的请求
            xhr.open('POST','http://127.0.0.1:8000/server');
            /**
             * 设置请求头,可以自定义请求头,需要在创建路由规则时将app.post改为app.all并且设置response.setHeader('Access-Control-Allow-Headers','*');
            */
            xhr.setRequestHeader('name','axiba');

            //3.发送
            /**
             * 设置请求体的方式:
             * xhr.send('a=10&b=20');xhr.send('a:10&b:20');xhr.send('5934hf938ut2');
            */
            xhr.send();
            
            // 4.事件绑定  处理服务端返回的结果
            // on 当...的时候   
            //readystate 是xhr对象中的属性,表示状态0(表示初始状态) 1(表示open方法已经调用完毕) 2(表示send方法已经调用完毕) 3(表示服务端已经返回部分结果) 4(表示服务端返回了所有的结果)
            //change 改变
            // 这个方法改一次触发一次
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){//结果为true,表示返回了所有结果
                    // 判断响应状态码 200 404 403 401 500,2开头的数字都表示成功
                    if(xhr.status >=200 && xhr.status<300){
                        // 处理结果
                        // console.log(xhr.status);//状态码
                        // console.log(xhr.statusText);//状态字符串
                        // console.log(xhr.getAllResponseHeaders);//所有响应头
                        // console.log(xhr.response);//响应体
                        result.innerHTML = xhr.response;
                    }else{

                    }
                }
            }
        }
    </script>
    
</body>

(3)、服务端返回字符串,我要转成JSON数据

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>

<body>
    <button>JSON</button>
    <div id="result"></div>

    <script>

        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");

        btn.onclick = function(){
            // console.log("----");
            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){
                        // console.log("--JSON--");
                        // result.innerHTML = xhr.response;

                        // 再将接收到的字符串手动转换成对象
                        // let data = JSON.parse(xhr.response);
                        // console.log(data);
                        // result.innerHTML = data.name;
                        // console.log(typeof(xhr.response));

                        //自动转换,需要在上面设置xhr.responseType = 'json';
                        console.log(xhr.response);
                        result.innerHTML = xhr.response.name;
                    }
                }
            }
        }
            
    </script>
</body>
//1.引入express
// const { response } = require('express');
// const { request } = require('express');
const express = require('express');

//2.创建应用对象
const app = express();

//3.创建路由规则
//get规则
app.get('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send('HELLO Ajax GET');
});
//post规则
app.all('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 设置响应体
    response.send('HELLO Ajax POST');
});
//用JSON的方法将对象转换成字符串
app.all('/json-server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*');

    // 设置一个对象数据
    const data = {
        name:'atguigu'
    };
    // 将data对象转换成字符串
    let str = JSON.stringify(data);
    // 设置响应体,发送字符串
    response.send(str);

});

//4.监听端口服务
app.listen(8000,()=>{
    console.log("服务器已启动...");
})

(4)、IE缓存问题:(ie已经g了)

IE浏览器会对ajax请求结果进行缓存,下一次请求时,ie浏览器会用缓存的数据,而服务端修改返回的数据后,无法显示修改的数据,所以对于时效性较强的数据就不能正常显示。

解决方法:

//在初始化的时候
xhr.open('POST','http://127.0.0.1:8000/ie?t='+Date.now());
//原理是传递数据的不变的就会使用原来的缓存的,而加上一个时间戳(因为生成的时间戳是不一样的)传递的数据就会变化,ie会重新获得服务端的值

(5)、ajax请求超时与网络异常处理

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>

<body>
    <button>JSON</button>
    <div id="result"></div>

    <script>
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");

        btn.onclick = function(){
            // console.log("----");
            const xhr = new XMLHttpRequest();

            xhr.open('GET','http://127.0.0.1:8000/delay');
            //2s超时设置
            xhr.timeout = 2000;
            xhr.ontimeout = function(){
                alert("你的网络似乎除了一些问题!");
            }
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        // console.log("--JSON--");
                        // result.innerHTML = xhr.response;
                        result.innerHTML = xhr.response;
                    }
                }
            }
        }
            
    </script>
    
</body>
//1.引入express
// const { response } = require('express');
// const { request } = require('express');
const express = require('express');

//2.创建应用对象
const app = express();

//3.创建路由规则
//get规则
app.get('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send('HELLO Ajax GET');
});
//post规则
app.all('/server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 设置响应体
    response.send('HELLO Ajax POST');
});
//用JSON的方法将对象转换成字符串
app.all('/json-server', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    //响应头
    response.setHeader('Access-Control-Allow-Headers','*');

    // 设置一个对象数据
    const data = {
        name:'atguigu'
    };
    // 将data对象转换成字符串
    let str = JSON.stringify(data);
    // 设置响应体,发送字符串
    response.send(str);

});

app.get('/delay', (request,response)=>{
    //设置响应头  设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置延时响应
    setTimeout( ()=>{
        //设置响应体
        response.send('延时响应');

    },3000);
});

//4.监听端口服务
app.listen(8000,()=>{
    console.log("服务器已启动...");
})

(6)、手动处理请求

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <button>点击取消请求</button>

    <script>
        const btn1 = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        const btn2 = document.getElementsByTagName('button')[1];

        var xhr = null;        
        btn1.onclick = function(){
            // console.log("----");
            xhr = new XMLHttpRequest();

            xhr.open('GET','http://127.0.0.1:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    if(xhr.status >= 200 && xhr.status < 300){
                        // console.log("--JSON--");
                        // result.innerHTML = xhr.response;
                        result.innerHTML = xhr.response;
                    }
                }
            }
        }
        btn2.onclick = function(){
            xhr.abort();
        }
            
    </script>
    
</body>

(7)、对于重复发送ajax请求问题,可以做一个判断

    <style>
        #result{
            width: 200px;
            height: 200px;
            border: solid 5px #bfa;
        }
    </style>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <button>点击取消请求</button>

    <script>
        const btn1 = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        const btn2 = document.getElementsByTagName('button')[1];
        var isSending = false;
        var xhr = null;        
        btn1.onclick = function(){
            // console.log("----");
            //判断是否正在发送请求,如果正在发,取消当前发送的请求
            if (isSending)  xhr.abort();
            xhr = new XMLHttpRequest();
            //修改表示变量为true
            isSending =true;

            xhr.open('GET','http://127.0.0.1:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    //发送完成修改表示变量为false 
                    isSending = false;

                    if(xhr.status >= 200 && xhr.status < 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
        }
        btn2.onclick = function(){
            xhr.abort();
        }   
    </script>
    
</body>

请求体只有post请求才可以发送。

(8)、同源策略

同源:协议、域名、端口号完全相同。

跨域:违背同源策略就是跨域。

如何解决跨域:

1、JSONP是一个非官方的跨域解决方案,是纯粹凭借程序有的聪明才智开发出来的,只支持get请求。

        网页中有些标签天生就具有跨域能力,比如:img link iframe script 。

        JSONP就是利script标签的跨域能力来发送请求的。

        

//1.引入express
// const { response } = require('express');
// const { request } = require('express');
const { request, response } = require('express');
const express = require('express');

//2.创建应用对象
const app = express();

//3.创建路由规则

// jsonp服务
app.all('/jsonp-server',(request,response)=>{
    response.send('hello jsonp-server----')
})

//4.监听端口服务
app.listen(8000,()=>{
    console.log("服务器已启动...");
})

使用script标签发请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- <script src="./server.js"></script> -->
    <!-- 先用上面的方式引入,然后在浏览器检查-网络-右键server.js在新标签页中打开 -->
    <!-- 这样src就能以网页地址的形式引入文件了 -->
    <!-- <script src="http://127.0.0.1:5500/ajaxStudy/jsonp%E5%A4%84%E7%90%86%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/server.js"></script> -->

    <!-- 通过上面的形式,我们可以在src写服务端的地址,这样就能获取服务端的数据了 -->
    <!-- src里面写服务器的地址,这样可以获得服务器返回的数据 -->
    <script src="http://127.0.0.1:8000/jsonp-server"></script>
    

</body>
</html>

2.CORS官方的解决跨域的方案,完全在服务器中进行处理,不需要客户端做任何操作。

支持get和post请求。

通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器受到后就会对响应放行。

//在服务端配置一些响应头即可,上面的例子能够发送请求收到数据都是因为配置了这个响应头。
//第二个参数*表示所有端口都能够发送请求。可以设置为http://127.0.0.1.5500就只允许这个端口发送请求。   
 response.setHeader('Access-Control-Allow-Origin','*');

有一组响应头可以用来设置。这里只是讲了一种

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值