Ajax
是基于 XMLHttpRequest(XHR)在前端开发中,咱们一种常见的网络请求方式就是 JSONPjavascript
使用 JSONP
最主要的缘由是为了解决跨域访问的问题。前端
JSONP 的原理是什么呢?vue
JSONP 如何封装呢?java
咱们一块儿本身来封装一个出来 JSONP的代码吧。node
let count = 1 export default function originPJSONP(option) { // 1. 从传入的 option 中提取 URL const url = option.url; // 2. 在body中添加 script 标签 const body = document.getElementsByTagName('body')[0]; const script = document.createElement('script'); // 3. 内部生成一个 不重复的 callback const callback = 'jsonp' + count++; // 4. 监听 window 上的 jsonp 的调用 return new Promise((resolve, roject) => { try { window[callback] = function (result) { body.removeChild(script); resolve(result) } const params = handleParam(option.data); body.appendChild(script) } catch (e) { body.removeChild(script) reject(e) } }) }
function handleParam(data) { let url = '' for (let key in data) { let value = data[key] !== undefined ? data[key] : '' url += `&${key} = ${encodeURIComponent(value)}` } return url }
axios : Ajax i/o systemjquery
支持多种请求方式ios
如何发送请求呢?ajax
案例:发送 get 请求json
import axios from 'axios' export default { name: 'app', created() { // 提问: 为何没有跨域问题 // 1. 没有请求参数 axios.get("http://www.liulongbin.top:3005/api/getlunbo") .then(res => { console.log(res); }).catch(err => { console.log(err); }) // 2. 有请求参数 axios.get('http://123.207.32.32:8000/home/data', {params: { type: 'sell', page: 1}}) .then(res => { console.log(res); }).catch(err => { console.log(err); }) } }
发送并发请求axios
有时候,咱们能够须要同时发送两个请求
使用 axios.all
, 能够放入多个请求的数组,
axios.all([])
返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 展开为 res1, res2
// 2. axios 发送并发请求 axios .all([ axios({ url: "http://www.liulongbin.top:3005/api/getlunbo" }), axios({ url: "http://123.207.32.32:8000/home/data", params: { type: "sell", page: 3 } }) ]) .then(res => { axios.spread((res1, res2) => { console.log(res1); console.log(res2); }); });
全局配置
在上面的实例中,咱们的 BaseURL 是固定的
事实上,在并发中肯不少参数都是固定的
这个时候咱们能够进行一些抽取,也能够利用axios的全局配置
axios.defaults.baseURL = 'http://www.liulongbin.top:3005/api' axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlenconded';
// 提取全局配置 axios.defaults.baseURL = "http://www.liulongbin.top:3005/api" axios .all([ axios({ url: "/getlunbo" }), axios({ // url: "http://123.207.32.32:8000/home/data", url: "/getnewslist", }) ]) .then(res => { axios.spread((res1, res2) => { console.log(res1); console.log(res2); }); });
为何要建立 axios 的实例呢
当咱们从 axios 模块中导入对象时,使用的实例是默认的实例
当给该实例设置一些默认配置时,这些配置就被固定下来了。
可是后续开发中,某些配置可能会不太同样
好比某些请求须要使用特定的 baseURL 或者 timeout 或者 content-Type 等
这个时候,咱们就能够建立新的实例,而且传入属于该实例的配置信息
// 建立新的实例 const axiosInstance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000, headers: {} })
```json // 发送网络请求 axiosInstance({ url: '/category', method: 'get' }).then(res => { console.log(res) }).catch(err) => { console.log(err) }
import originAxios from 'axios' export default function axios(option) { return new Promise((reslove, reject) => { // 1. 建立 axios 的实例 const instance =originAxios.create({ baseURL: 'api', timeout: 5000 }) // 2. 传入对象进行网络请求 instance(option).then(res => { resolve(res) }).catch(err => { reject(err) }) }) }
axios 提供了拦截器,用于咱们在发送每次请求或者获得响应后,进行对应的处理。
如何使用拦截
// 配置请求和响应拦截 instance.interceptors.request.use(config => { // 请求拦截成功 console.log('来到了 request 拦截 success中') return config }, err => { // 请求拦截失败 console.log('request 拦截 failure 中') }) instance.interceptors.response.use(response => { // 响应拦截成功 console.log('来到了 response 拦截 success 中') return response.data }, err => { // 响应拦截失败 console.log('来到了 response 拦截 failure 中') return err })