Ajax
是基于 XMLHttpRequest(XHR)在前端开发中,我们一种常见的网络请求方式就是 JSONP
使用 JSONP
最主要的原因是为了解决跨域访问的问题。
JSONP 的原理是什么呢?
JSONP 如何封装呢?
我们一起自己来封装一个出来 JSONP的代码吧。
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 system
支持多种请求方式
如何发送请求呢?
案例:发送 get 请求
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.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
})
参与评论
手机查看
返回顶部