# Ajax ## 一、Ajax简介 **Ajax**(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)是一种用于创建快速动态网页的技术。 它的核心思想是:**在不需要重新加载整个网页的情况下,能够与服务器交换数据并更新部分网页内容。** 简单来说,以前我们填写一个表单,点击提交后页面会“白屏”一下然后刷新,这就是同步方式。而使用 Ajax,你点击提交后,页面无感,但数据已经在后台发送和接收了,然后JavaScript再悄悄地更新页面中需要变化的部分。 ## 二、提供练习数据的第三方API 1、天气预报 - 天行数据(可直接跨域访问) [天气预报API接口 - 天聚数行TianAPI](https://www.tianapi.com/apiview/72) 2、新闻头条 - 聚合数据(不可直接跨域访问) [新闻API接口 - 天聚地合](https://www.juhe.cn/docs/api/id/235) ## 三、Ajax使用 `XMLHttpRequest`对象是Ajax应用程序的核心,当客户端发出请求时,请求数据需要发送给`XMLHttpRequest`对象并不是服务器,由该对象异步请求服务器,并且服务器返回的数据是返回给`XMLHttpRequest`对象的。 #### 1、创建Ajax对象 创建一个普通工程,创建`index.html`文件 ```html Title ``` #### 2、处理异步请求结果 ##### 请求响应状态 监听响应状态(readyState)需要用到`onreadystatechange`事件 * `0`:未初始化,还没有调用send(); * `1`:载入,已经初始化,已建立服务器连接; * `2`:载入完成,send()方法执行完成,已经接收到全部的响应内容; * `3`:交互,正在解析响应内容; * `4`:完成,响应内容解析完成,可以在客户端使用。 ##### 处理请求响应 ```html Title ``` # Axios框架 ## 一、Axios框架介绍 Axios 是一个基于 Promise 的、用于浏览器和 Node.js 的 HTTP 客户端。它本质上是一个封装得更友好、功能更强大的库,用来代替浏览器原生的 `XMLHttpRequest` 或 `fetch` API 来发送 Ajax 请求。 Axios可以使前端应用和后台服务器之间更安全、更高效地收发数据。 官网:[起步 | Axios中文文档 | Axios中文网](https://www.axios-http.cn/docs/intro) ## 二、安装 #### 1、CDN直接引用 ```html ``` #### 2、npm安装 ## 三、响应结构 ```json { // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 是服务器响应头 // 所有的 header 名称都是小写,而且可以使用方括号语法访问 // 例如: `response.headers['content-type']` headers: {}, // `config` 是 `axios` 请求的配置信息 config: {}, // `request` 是生成此响应的请求 // 在node.js中它是最后一个ClientRequest实例 (in redirects), // 在浏览器中则是 XMLHttpRequest 实例 request: {} } ``` 当使用 `then` 时,将接收如下响应 ```js axios.get('/user/12345') .then((response) => { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); ``` ## 四、HTML使用 #### 1、GET方式请求 ```html Title ``` #### 2、POST请求 ```html Title ``` #### 3、请求参数处理函数 当发送的是一个对象但是服务器不支持处理对象参数时,可以用下面的函数将对象展开成字符串发送。 ```js function transformRequest(data) { let ret = ''; for (let it in data) { ret += encodeURIComponent(it) + "=" + encodeURIComponent(data[it]) + "&"; } return ret; } ``` #### 4、全局配置 ##### 设置全局基础URL ```js axios.defaults.baseURL = 'https://apis.tianapi.com/'; ``` ##### 设置请求头 ```js axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; ``` ##### 设置超时时长 ```js axios.defaults.timeout = 2500; ``` #### 5、拦截器 在请求或响应之前对数据进行再次处理 ```js // 添加请求拦截器 axios.interceptors.request.use((config) => { // 在发送请求之前做些什么 return config; }, (error) => { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use((response) => { // 2xx 范围内的状态码都会触发该函数。 // 对响应数据做点什么 return response; }, (error) => { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 return Promise.reject(error); }); ``` ## 四、Vue使用 #### 1、安装Axios 在项目文件目录下的终端运行下面命令 ```bash npm install axios ```  #### 2、天气预报页面 ```html 上海市七天天气预报 最低气温: 最高气温: 体感气温: 风向: 温馨提示: ``` **注意**:为了防止请求返回数据错误,所以要做状态判断,并且为了防止数据返回之前进行遍历出现错误,需要控制列表在数据返回正确后再创建。  ## 五、Vue跨域访问 #### 1、同源策略 同源策略是浏览器实施的一种核心安全机制,旨在限制来自不同“源”的文档或脚本如何与另一个资源进行交互。 一个“源”由三部分组成: - **协议**:例如 `http`、`https` - **域名/IP**:例如 `www.example.com` - **端口**:例如 `80`(HTTP默认端口)、`443`(HTTPS默认端口) **同源判定**:只有当两个URL的**协议、域名、端口**三者完全一致时,才被认为是同源的 **示例**: - `https://www.example.com/page.html` 与 `https://www.example.com/api/` **同源**(协议、域名、端口相同)。 - `https://www.example.com/page.html` 与 `http://www.example.com/page.html` **不同源**(协议不同,https vs http)。 - `https://www.example.com/page.html` 与 `https://api.example.com/page.html` **不同源**(域名不同,主域名 vs 子域名)。 - `https://www.example.com/page.html` 与 `https://www.example.com:8080/page.html` **不同源**(端口不同,443 vs 8080)。 #### 2、跨域访问 当与不同源的地址进行访问时,即为跨域访问,默认Ajax不允许跨域访问。 以聚合数据的新闻头条请求为例:  允许跨域访问需要通过修改`vue.config.json`文件中的配置来实现 ```js const {defineConfig} = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { proxy: { // 本地代理URL '/juheNews': { target: 'http://v.juhe.cn/toutiao/index', // 需要跨域的URL ws: true, // 使用Websocket进行代理 changeOrigin: true, // 设置允许跨域 pathRewrite: { '^/juheNews': '' // 重写请求时的代理路径 } } } } }) ``` **注意**:重写的路径前面`^`表示匹配以该路径开头的路径,若不加`^`则会将所有包含`/juheNews`的路径中的`/juheNews`替换成`''`,如果不进行代理路径替换会将代理路径直接拼接到请求路径上:`http://v.juhe.cn/toutiao/index/juheNews?key=***` 前端只需要通过访问代理路径即可正常请求 ```js import axios from "axios"; import {ref} from "vue"; const data = ref({}); const isShow = ref(false); // GET请求 axios.get('/juheNews', { params: { key: "[APIKEY]" } }).then((response) => { data.value = response.data; console.log(data.value); if (data.value.error_code !== 0) { throw new Error("[API]"+ data.value.reason); } isShow.value = true; }).catch((error) => { console.log(error) }); ``` Loading... # Ajax ## 一、Ajax简介 **Ajax**(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)是一种用于创建快速动态网页的技术。 它的核心思想是:**在不需要重新加载整个网页的情况下,能够与服务器交换数据并更新部分网页内容。** 简单来说,以前我们填写一个表单,点击提交后页面会“白屏”一下然后刷新,这就是同步方式。而使用 Ajax,你点击提交后,页面无感,但数据已经在后台发送和接收了,然后JavaScript再悄悄地更新页面中需要变化的部分。 ## 二、提供练习数据的第三方API 1、天气预报 - 天行数据(可直接跨域访问) [天气预报API接口 - 天聚数行TianAPI](https://www.tianapi.com/apiview/72) 2、新闻头条 - 聚合数据(不可直接跨域访问) [新闻API接口 - 天聚地合](https://www.juhe.cn/docs/api/id/235) ## 三、Ajax使用 `XMLHttpRequest`对象是Ajax应用程序的核心,当客户端发出请求时,请求数据需要发送给`XMLHttpRequest`对象并不是服务器,由该对象异步请求服务器,并且服务器返回的数据是返回给`XMLHttpRequest`对象的。 #### 1、创建Ajax对象 创建一个普通工程,创建`index.html`文件 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> // 创建XMLHttpRequest核心对象 const xhr = new XMLHttpRequest(); // 使用open()方法创建http请求 xhr.open('get','https://apis.tianapi.com/tianqi/index?key=[APIKEY]&city=101020100&type=1'); // 向服务端发送请求 xhr.send(null); </script> </body> </html> ``` #### 2、处理异步请求结果 ##### 请求响应状态 监听响应状态(readyState)需要用到`onreadystatechange`事件 * `0`:未初始化,还没有调用send(); * `1`:载入,已经初始化,已建立服务器连接; * `2`:载入完成,send()方法执行完成,已经接收到全部的响应内容; * `3`:交互,正在解析响应内容; * `4`:完成,响应内容解析完成,可以在客户端使用。 ##### 处理请求响应 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> // 创建XMLHttpRequest核心对象 const xhr = new XMLHttpRequest(); // 使用open()方法创建http请求 xhr.open('get', 'https://apis.tianapi.com/tianqi/index?key=[APIKEY]&city=101020100&type=1'); // 向服务端发送请求 xhr.send(null); // 监控响应状态 let result; xhr.onreadystatechange = () => { if (xhr.readyState === 4 && xhr.status === 200) { test(xhr.responseText); } }; // 处理响应数据 function test(result){ this.result = result; console.log(this.result); } </script> </body> </html> ``` # Axios框架 ## 一、Axios框架介绍 Axios 是一个基于 Promise 的、用于浏览器和 Node.js 的 HTTP 客户端。它本质上是一个封装得更友好、功能更强大的库,用来代替浏览器原生的 `XMLHttpRequest` 或 `fetch` API 来发送 Ajax 请求。 Axios可以使前端应用和后台服务器之间更安全、更高效地收发数据。 官网:[起步 | Axios中文文档 | Axios中文网](https://www.axios-http.cn/docs/intro) ## 二、安装 #### 1、CDN直接引用 ```html <script src="https://unpkg.com/axios/dist/axios.min.js"></script> ``` #### 2、npm安装 ## 三、响应结构 ```json { // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 是服务器响应头 // 所有的 header 名称都是小写,而且可以使用方括号语法访问 // 例如: `response.headers['content-type']` headers: {}, // `config` 是 `axios` 请求的配置信息 config: {}, // `request` 是生成此响应的请求 // 在node.js中它是最后一个ClientRequest实例 (in redirects), // 在浏览器中则是 XMLHttpRequest 实例 request: {} } ``` 当使用 `then` 时,将接收如下响应 ```js axios.get('/user/12345') .then((response) => { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); ``` ## 四、HTML使用 #### 1、GET方式请求 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <script> // GET请求参数一体 axios.get('https://apis.tianapi.com/tianqi/index?key=[APIKEY]&city=101020100&type=1') .then((response) => { console.log(response.data) }).catch((error) => { console.log(error) }); // GET请求参数分离 axios.get('https://apis.tianapi.com/tianqi/index', { params: { key: "[KEYAPI]", city: "101020100", type: "1" } }) .then((response) => { console.log(response) }).catch((error) => { console.log(error) }); </script> </body> </html> ``` #### 2、POST请求 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <script> function transformRequest(data) { let ret = ''; for (let it in data) { ret += encodeURIComponent(it) + "=" + encodeURIComponent(data[it]) + "&"; } return ret; } // POST请求 axios.post('https://apis.tianapi.com/tianqi/index', transformRequest({ key: "[APIKEY]", city: "101020100", type: "1" })) .then((response) => { console.log(response.data) }).catch((error) => { console.log(error) }); </script> </body> </html> ``` #### 3、请求参数处理函数 当发送的是一个对象但是服务器不支持处理对象参数时,可以用下面的函数将对象展开成字符串发送。 ```js function transformRequest(data) { let ret = ''; for (let it in data) { ret += encodeURIComponent(it) + "=" + encodeURIComponent(data[it]) + "&"; } return ret; } ``` #### 4、全局配置 ##### 设置全局基础URL ```js axios.defaults.baseURL = 'https://apis.tianapi.com/'; ``` ##### 设置请求头 ```js axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; ``` ##### 设置超时时长 ```js axios.defaults.timeout = 2500; ``` #### 5、拦截器 在请求或响应之前对数据进行再次处理 ```js // 添加请求拦截器 axios.interceptors.request.use((config) => { // 在发送请求之前做些什么 return config; }, (error) => { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use((response) => { // 2xx 范围内的状态码都会触发该函数。 // 对响应数据做点什么 return response; }, (error) => { // 超出 2xx 范围的状态码都会触发该函数。 // 对响应错误做点什么 return Promise.reject(error); }); ``` ## 四、Vue使用 #### 1、安装Axios 在项目文件目录下的终端运行下面命令 ```bash npm install axios ```  #### 2、天气预报页面 ```html <template> <div> <h2>上海市七天天气预报</h2> <ul v-if="isShow" style="list-style-type:none;padding: 0"> <li v-for="item in data.result.list" :key="item.date"> <span v-text="item.date"></span> <span v-text="item.week"></span> <span v-text="item.weather"></span> 最低气温:<span v-text="item.lowest"></span> 最高气温:<span v-text="item.highest"></span> 体感气温:<span v-text="item.real"></span> 风向:<span v-text="item.wind"></span><br> 温馨提示:<span v-text="item.tips"></span> </li> </ul> </div> </template> <script setup> import axios from "axios"; import {ref} from "vue"; const data = ref({}); const isShow = ref(false); // GET请求 axios.get('https://apis.tianapi.com/tianqi/index', { params: { key: "[APIKEY]", city: "101020100", type: "7" } }).then((response) => { data.value = response.data; if (data.value.code !== 200) { throw new Error("[API]"+ data.value.msg) } console.log(data); isShow.value = true; }).catch((error) => { console.log(error) }); </script> ``` **注意**:为了防止请求返回数据错误,所以要做状态判断,并且为了防止数据返回之前进行遍历出现错误,需要控制列表在数据返回正确后再创建。  ## 五、Vue跨域访问 #### 1、同源策略 同源策略是浏览器实施的一种核心安全机制,旨在限制来自不同“源”的文档或脚本如何与另一个资源进行交互。 一个“源”由三部分组成: - **协议**:例如 `http`、`https` - **域名/IP**:例如 `www.example.com` - **端口**:例如 `80`(HTTP默认端口)、`443`(HTTPS默认端口) **同源判定**:只有当两个URL的**协议、域名、端口**三者完全一致时,才被认为是同源的 **示例**: - `https://www.example.com/page.html` 与 `https://www.example.com/api/` **同源**(协议、域名、端口相同)。 - `https://www.example.com/page.html` 与 `http://www.example.com/page.html` **不同源**(协议不同,https vs http)。 - `https://www.example.com/page.html` 与 `https://api.example.com/page.html` **不同源**(域名不同,主域名 vs 子域名)。 - `https://www.example.com/page.html` 与 `https://www.example.com:8080/page.html` **不同源**(端口不同,443 vs 8080)。 #### 2、跨域访问 当与不同源的地址进行访问时,即为跨域访问,默认Ajax不允许跨域访问。 以聚合数据的新闻头条请求为例:  允许跨域访问需要通过修改`vue.config.json`文件中的配置来实现 ```js const {defineConfig} = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { proxy: { // 本地代理URL '/juheNews': { target: 'http://v.juhe.cn/toutiao/index', // 需要跨域的URL ws: true, // 使用Websocket进行代理 changeOrigin: true, // 设置允许跨域 pathRewrite: { '^/juheNews': '' // 重写请求时的代理路径 } } } } }) ``` **注意**:重写的路径前面`^`表示匹配以该路径开头的路径,若不加`^`则会将所有包含`/juheNews`的路径中的`/juheNews`替换成`''`,如果不进行代理路径替换会将代理路径直接拼接到请求路径上:`http://v.juhe.cn/toutiao/index/juheNews?key=***` 前端只需要通过访问代理路径即可正常请求 ```js import axios from "axios"; import {ref} from "vue"; const data = ref({}); const isShow = ref(false); // GET请求 axios.get('/juheNews', { params: { key: "[APIKEY]" } }).then((response) => { data.value = response.data; console.log(data.value); if (data.value.error_code !== 0) { throw new Error("[API]"+ data.value.reason); } isShow.value = true; }).catch((error) => { console.log(error) }); ``` 最后修改:2025 年 11 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。