尚硅谷 AJAX

一、原生 AJAX

(一) AJAX简介

AJAX 全称 Asynchronous JavaScript And XML,就是 异步的 JS 和 XML

通过 AJAX 可以 在浏览器中向服务器发送异步请求最大的优势无刷新获取数据

AJAX 不是新的变成语言,而是一种将现在的标准组合在一起使用的新方式。


(二) XML简介

XML 可扩展标记语言。

XML 被设计用来传输和存储数据

XML和HTML类似,不同的是 HTML中都是预定义标签,而 XML 中没有预定义标签,全都是自定义标签,用来表示一些数据。

比如说我有一个学生数据:
 name = "孙悟空; age=18; gender="男";
用XML表示: 
 <student>
    <name>孙悟空</name>
    <age>18</age>
    <gender>男</gender>
 </student>

现在已经被 JSON 取代了。

用 JSON 表示
{"name":"孙悟空","age":18;"gender":"男"}

(三) AJAX的特点

AJAX的优点:

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

  2. 允许你根据 用户事件(鼠标、键盘事件) 来更新部分页面内容。

AJAX的缺点

  1. 没有浏览历史,不能回退

  2. 存在跨域问题 (同源)

  3. SEO 不友好


二、Node.js

(一) 安装

下载网址:Download | Node.js

检测是否安装成功: 按win+R ,输入cmd在命令提示符下输入node -v.


(二) Express 框架

基于 Node.js 平台,快速、开放、极简的 web 开发框架

(1) 基本使用

安装 Express框架


1 初始化


2 安装 express 框架


// 1.引入 express
const express = require('express')
// 2. 创建应用对象
const app = express()
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对相应报文的封装
app.get('/',(request,response)=>{
    // 设置响应
    response.send('hello express');
})
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
})

3 启动服务器


4 关闭服务器

按下 Ctrl + C

三、AJAX案例准备

<style>
    #result {
        width: 200px;
        height: 100px;
        border: 1px solid #90b;
    }
</style>
<button>点击发送请求</button>
<div id="result"></div>
​
<script>
    // 1.引入 express
const express = require('express')
// 2. 创建应用对象
const app = express()
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对相应报文的封装
app.get('/server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    // response.send('hello ajax');
})
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
})
</script>

(一) AJAX GET请求的基本步骤

<button>点击发送请求</button>
<div id="result"></div>
<script>
    // 获取button元素
    const btn = document.querySelector('button');
    const result = document.querySelector('div');
    // 绑定数据 
    btn.onclick = function () {
        // 1. 创建对象
        const xhr = new XMLHttpRequest();
        // 2. 初始化 设置请求方法 和 url
        xhr.open('GET', 'http://127.0.0.1:8000/server');
        // 3.发送
        xhr.send()
        // 4. 事件绑定 处理服务端返回的结果
        // on 当...时候
        // readstate 是xhr对象中的属性,表示状态 0 1 2 3 4
        // change 改变
        xhr.onreadystatechange = function () {
            // 判断 (4 服务端返回了所有结果)
            if (xhr.readyState === 4) {
                // 判断响应状态码 200 404 500
                // 2xx 成功
                if (xhr.status >= 200 && xhr.status < 300) {
                    result.innerHTML = xhr.response;
                }
            }
        }
​
    }
</script>

<script>
    // 1.引入 express
const express = require('express')
// 2. 创建应用对象
const app = express()
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对相应报文的封装
app.get('/server',(request,response)=>{
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    // response.send('hello ajax');
})
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口监听中...");
})
</script>

(二) AJAX 设置请求参数

// 2. 初始化 设置请求方法 和 url
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');

(三) AJAX POST请求

<style>
    #result {
        width: 200px;
        height: 100px;
        border: 1px solid #903;
    }
</style>
​
<div id="result"></div>
<script>
// 获取元素对象
const result = document.querySelector('#result');
result.addEventListener("mouseover",function(){
    // 1. 创建对象
        const xhr = new XMLHttpRequest();
        // 2. 初始化 设置请求方法 和 url
        xhr.open('POST', 'http://127.0.0.1:8000/server');
        // 3.发送
        xhr.send('a=100&b=200')
        // 4. 事件绑定 处理服务端返回的结果
        // on 当...时候
        // readstate 是xhr对象中的属性,表示状态 0 1 2 3 4
        // change 改变
        xhr.onreadystatechange = function () {
            // 判断 (4 服务端返回了所有结果)
            if (xhr.readyState === 4) {
                // 判断响应状态码 200 404 500
                // 2xx 成功
                if (xhr.status >= 200 && xhr.status < 300) {
                    result.innerHTML = xhr.response;
                }
            }
        }
})
</script>

(四) POST 设置请求体

// 3.发送
xhr.send('a=100&b=200');

(五) AJAX设置请求头信息

// 2. 初始化 设置请求方法 和 url
xhr.open('GET', 'http://127.0.0.1:8000/server');
​
// 设置请求头
// Content-Type用来设置请求体内容的类型
xhr.setRequestHeader('Content-Type','application/x-www-form-rulencoder');
xhr.setRequestHeader('name','atguigu'); // 自定义请求头会报错,浏览器会有安全机制,不让发

// 解决办法
// 服务器设置响应头
    response.setHeader('Access-Control-Allow-Header','*')
// 还是报错 option
--------------------------------------------------
// 解决办法
将服务器请求方式改成 all
app.all('/',(request,response)=>{
    // 设置响应
    response.send('hello express');
})

四、服务端响应 JSON 数据

手动转换

// 1.引入 express
const express = require('express')
// 2. 创建应用对象
const app = express()
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对相应报文的封装
app.get('/json-server', (request, response) => {
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    // 设置响应体
    // response.send('hello ajax post');
    // 响应一个数据
    const data = {
        name: 'atguigu'
    };
    // 对对象进行字符串转换
    let str = JSON.stringify(data);
    // 设置响应体
    response.send(str);
})
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中...");
})
​

<script>
        const result = document.querySelector('#result');
        result.addEventListener("mouseover", 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) {
                    let data = JSON.parse(xhr.response);
                        result.innerHTML = data.name;
                    }
                }
            }
        })
</script>

自动转换


<script>
​
        // 获取元素对象
        const result = document.querySelector('#result');
        result.addEventListener("mouseover", function () {
            // 1. 创建对象
            const xhr = new XMLHttpRequest();
            // 设置响应体数据类型
            xhr.responseType ='json';
            // 2. 初始化 设置请求方法 和 url
            xhr.open('GET', 'http://127.0.0.1:8000/json-server');
            // 3.发送
            xhr.send()
            // 4. 事件绑定 处理服务端返回的结果
            // on 当...时候
            // readstate 是xhr对象中的属性,表示状态 0 1 2 3 4
            // change 改变
            xhr.onreadystatechange = function () {
                // 判断 (4 服务端返回了所有结果)
                if (xhr.readyState === 4) {
                    // 判断响应状态码 200 404 500
                    // 2xx 成功
                    if (xhr.status >= 200 && xhr.status < 300) {
                    // 自动转换
                    result.innerHTML = xhr.response.name;
                    }
                }
            }
        })
    </script>

五、nodemon自动重启工具

网址:nodemon - npm

运行一条指令:

npm install -g nodemon

可能出现的问题

首次在计算机上启动 Windows PowerShell 时,现用执行策略很可能是 Restricted(默认设置)。Restricted 策略不允许任何脚本运行。 那么就需要收到开启运行脚本:

win+x 打开PowerShell(管理员)
set-ExecutionPolicy RemoteSigned //设置为打开
在这里插入图片描述
键入Y或者A,同意
执行get-executionpolicy查看是否更改成功,为RemoteSigned表示成功
在这里插入图片描述
一般到这里就可以执行问题了。

六、AJAX常见问题

(一) IE缓存问题解决

更改为: xhr.open('GET', 'http://127.0.0.1:8000/ie?t='+Date.now());

// 1.引入 express
const express = require('express')
// 2. 创建应用对象
const app = express()
// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对相应报文的封装
app.get('/ie', (request, response) => {
    // 设置响应头,设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*');
    // 设置响应体
    // response.send('hello IE');
})
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中...");
})


<style>
    #result {
        width: 200px;
        height: 100px;
        border: 1px solid #903;
    }
<button>点击发送请求</button>
<div id="result"></div>
<script>
    const btn = document.querySelector('button');
    const result = document.querySelector('#result');
    btn.addEventListener('click', function () {
        // 1. 创建对象
        const xhr = new XMLHttpRequest();
        // 设置响应体数据类型
        xhr.responseType ='json';
        // 2. 初始化 设置请求方法 和 url
        // 解决IE缓存问题
        xhr.open('GET', 'http://127.0.0.1:8000/ie?t='+Date.now());
        // 3.发送
        xhr.send()
        // 4. 事件绑定 处理服务端返回的结果
        // on 当...时候
        // readstate 是xhr对象中的属性,表示状态 0 1 2 3 4
        // change 改变
        xhr.onreadystatechange = function () {
        // 判断 (4 服务端返回了所有结果)
        if (xhr.readyState === 4) {
        // 判断响应状态码 200 404 500
        // 2xx 成功
        if (xhr.status >= 200 && xhr.status < 300) {
        // 自动转换
        result.innerHTML = xhr.response.name;
        }
                }
            }
    })
    
</script>

(二) AJAX请求超时与网络异常

const express = require('express')
const app = express()
app.get('/delay', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    // 设置定时器
    setTimeout(()=>{
        response.send('延时响应');
    },3000)
})
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中...");
})

<style>
    #result {
        width: 200px;
        height: 100px;
        border: 1px solid #903;
    }
<button>点击发送请求</button>
<div id="result"></div>
<script>
    const btn = document.querySelector('button');
    const result = document.querySelector('#result');
    btn.addEventListener('click', function () {
        const xhr = new XMLHttpRequest();
        // 超时设置 2s 设置
        xhr.timeout = 2000;
        // 超时回调
        xhr.ontimeout = function(){
            alert('网络异常,请稍后重试');
        }
        // 网络异常回调
        xhr.onerror = function(){
            alert('网络似乎出了点问题');
        }
        xhr.open('GET', 'http://127.0.0.1:8000/delay);
        xhr.send()
        xhr.onreadystatechange = function () {
        // 判断 (4 服务端返回了所有结果)
        if (xhr.readyState === 4) {
        // 判断响应状态码 200 404 500
        // 2xx 成功
        if (xhr.status >= 200 && xhr.status < 300) {
        // 自动转换
        result.innerHTML = xhr.response.name;
        }
                }
            }
    })
    
</script>

(三) AJAX取消请求

const express = require('express')
const app = express()
app.get('/delay', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    // 设置定时器
    setTimeout(()=>{
        response.send('延时响应');
    },3000)
})
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中...");
})

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

(四) AJAX 请求重复发送问题

const express = require('express')
const app = express()
app.get('/delay', (request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-headers', '*');
        response.send('延时响应');
})
app.listen(8000, () => {
    console.log("服务已经启动,8000端口监听中...");
})

<button>点击发送</button>
<script>
    const btns = document.querySelectorAll('button');
    let x = null;
    // 标识变量
    let isSending = false;  // 是否正在发送AJAX请求
    btns[0].onclick = function () {
        // 判断标识变量
        if(isSending) x.abort();    // 如果正在发送,则取消该请求,创建一个新的请求
        x = new XMLHttpRequest();
        // 修改 标识变量的值
        isSending= true;
        x.open("GET", 'http://127.0.0.1:8000/delay');
        x.send();
       x.onreadystatechange = function(){
        if(x.ready === 4){
            // 修改标识变量
             isSending = false;
        }
       }
    }
</script> 

七、axios 发送AJAX请求

(一) 引入axios

<script crossorigin= "anonymous" src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>

<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
    const btns = document.querySelectorAll('button');
    // 配置 baseURL
    axios.defaults.baseURL = 'http://127.0.0.1:8000';
    axios.post('/axios-server', {
        // 请求体
        username: 'admin',
        password: 'admin'
    }, {
        // url 参数
        params: {
            id: 100,
            vip: 7
        },
        // 请求头信息
        headers: {
            name: 'atguigu',
            age: 20
        },
​
    })
​
</script>

(二) AXIOS函数发送AJAX请求

<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
    const btns = document.querySelectorAll('button');
    // 配置 baseURL
    axios.defaults.baseURL = 'http://127.0.0.1:8000';
    btns[2].onclick = function () {
        axios({
            method: 'POST',
            url: '/axios-server',
            // url 参数
            params: {
                vip: 10,
                level: 30
            },
            headers: {
                a: 100,
                b: 200
            },
            data: {
                username: 'admin',
                password: 'admin'
            }
        })
    }
</script>

(三) 使用fetch函数发送 AJAX请求

<button>AJAX请求</button>
<script>
	const btn = document.querySelector('button');
	btn.onclick = function(){
		fetch('http://127.0.0.1:8000/fetch-server',{
			// 请求方法
			method: 'POST',
			// 请求头
			headers: {
				name: 'atguigu'
			},
			// 请求体
			body: 'username=admin&password=admin'
                }).then(response =>{
                    return response.text();
                }).then(response =>{
                    console.log(response);
                })
	}
</script>

八、跨域

同源策略最早由 Netscape 公司提出,是浏览器的一种安全策略。

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

违背同源策略就是跨域。

// server.js
const express = require('express');

const app = express();

app.get('/home', (request, response) => {
    // 响应一个页面
    response.sendFile(__dirname + '/index.html');
});
app.get('/data', (request, response) => {
    response.send("用户数据");
});
app.listen(9000, () => {
    console.log('服务以及启动...');
})

<h1>尚硅谷</h1>
<button>点击获取用户数据</button>
<script>
    const btn = document.querySelector('button');
    btn.onclick = function () {
        const x = new XMLHttpRequest();
        // 因为是满足同源策略,所以url可以简写
        x.open("GET", '/data');
        // 发送
        x.send();
        x.onreadystatechange = function () {
            if (x.readyState === 4) {
                if (x.status >= 200 && x.status < 300) {
                    console.log(x.response);
                }
            }
        }
    }
</script>

(一) JSONP

1 JSONP是什么

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

2 JSONP怎么工作的?

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

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

3 JSONP的使用

  1. 动态的创建一个 script 标签

var script = document.createElement("script");
  1. 设置 script的 src,设置回调函数


// index.html
<script    src="http://127.0.0.1:5500/%E5%AD%A6%E6%88%90%E5%9C%A8%E7%BA%BF%E6%A1%88%E4%BE%8B/%E6%A1%88%E4%BE%8B2/get.js"></script>

// get.js
const data = {
    name: '黑马程序员niubai'
}
console.log(data);
handle(data)

// 更改后的index.html
<div id="result"></div>
    <script>
        function handle(data) {
            // 获取 result 元素
            const result = document.getElementById('result');
            result.innerHTML = data.name;
        }
    </script>
    <script src="http://127.0.0.1:9000/jsonp-server"></script>

app.get('/jsonp-server', (request, response) => {
    // response.send("console.log('hello jsonp')");
    const data = {
        name: '尚硅谷'
    };
    // 将数据转化为字符串
    let str = JSON.stringify(data);
    // 返回结果
    response.end(`handle(${str})`);
});

(二) 原生JSONP的实现

用户名: <input type="text" id="username">
    <p></p>
    <script>
        // 获取 input元素
        const input = document.querySelector('input');
        const p = document.querySelector('p');
        // 声明 handle 函数
        function handle(data) {
            input.style.border = "1px solid #f00";
            // 修改 p 标签的提示文本
            p.innerHTML = data.msg;
        }
        // 绑定事件
        input.onblur = function () {
            // 获取用户的输入值
            let username = this.value;
            // 向服务端发送请求,检测用户名是否存在
            // 1.创建 script标签
            const script = document.createElement('script');
            // 2.设置标签的src属性
            script.src = "http://127.0.0.1:9000/check-username";
            // 3.将script插入到文档中
            document.body.appendChild(script);
        }
    </script>

// 用户名检测
app.all('/check-username', (request, response) => {
    const data = {
        exist: 1,
        msg: '用户名已经存在'
    };
    // 将数据转化为字符串
    let str = JSON.stringify(data);
    // 返回结果
    response.end(`handle(${str})`);
});

(三) CORS

网址:mozillla.org

1 CORS是什么?

CORS,跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

2 CORS怎么工作的?

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

3 CORS的使用

主要是服务器端的设置:

// 跨域
response.setHeader("Access-Control-Allow-Origin","*");
// 请求头允许自定义
response.setHeader("Access-Control-Allow-Headers","*");
// 请求方法任意
response.setHeader("Access-Control-Allow-Method","*");

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值