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 })