今天學習了vue的兩種發(fā)送請求的方式,vueResource和axios,比較了兩種方式的使用
VueResource模塊發(fā)送請求
1. VueResource概述
- VueJS的生態(tài)圈除了VueRouter之外,還有很多的插件,在網(wǎng)絡請求中,vue是借助于vue-resource模塊來進行異步請求,跨域請求。
- vue-resource是Vue.js的一款插件,它可以通過XMLHttpRequest或JSONP發(fā)起請求并處理響應。也就是說,$.ajax能做的事情,vue-resource插件一樣也能做到,而且vue-resource的API更為簡潔。
- 特點
- 體積小,vue-resource非常小巧,在壓縮以后只有大約12KB,服務器啟用gzip壓縮后只有4.5KB大小。
- 支持主流的瀏覽器,和vuejs一樣,vue-resource除了不支持IE9以下的瀏覽器,其他主流的瀏覽器都支持。
- 支持PromiseAPI和URI Templates,Promise是es6的特性,Promise的中文含義為"先知",Promise對象用于異步計算。URl Templates表示URI模塊,有些類似于ASP.NET MVC的路由模塊。
- 支持攔截器
攔截器是全局的,攔截器可以在請求發(fā)送前和發(fā)送請求后做一些處理。
攔截器在一些場景上非常有用,比如請求發(fā)送前在headers中設置access_token,或者在請求失敗時,提供共通的處理方式。
2. VueResource的使用步驟
-
使用步驟
-
cdn 下載網(wǎng)址
https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js -
安裝vue-resource
npm install --save vue-resource
- 引入vue-resource模塊
import VueResource from 'vue-resource'
Vue.use(VueResource)
- 調用模塊中$http發(fā)起請求
this.$http.get('url')
.then(function(response){
....
})
- 在組件實例加載完之后,會自動調用vueResource這個模塊
<script>
Vue.use(vueResource)
new Vue({
el:'#app',
mounted(){
this.$http.get('http://localhost:5050/index')
.then(result=>{
console.log(result.data)
}) //發(fā)送get請求
this.$http.get('http://localhost:5050/details',{
params:{lid:5}
}).then(result=>{
console.log(result.data)
}) //發(fā)送帶數(shù)值的get請求
this.$http.post('http://localhost:5050/users/signin',{
uname:"dingding",
upwd:'123456'
}).then(result=>{
console.log(result.data)
})//發(fā)送post請求
}
})
</script>
axios方式發(fā)送請求
1. axios概述
- 從vue2.0開始已經(jīng)在推崇用新的方法(axios)來代替vue-resource
- Axios跟vue無關,在任何平臺都可以發(fā)送請求,比如nodejs 網(wǎng)頁等
- 所以從新版的vue開始,vue-resource已經(jīng)不再被使用
2. axios的使用步驟
- cli中axios的使用
// main.js
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
注冊方式1:Vue.use(VueAxios,axios)
注冊方式2:Vue.prototype.axios=axios
//使用
this.axios.get('demo/getTest?user=tom')
.then((res)=>{
console.log(res.data)
})
- html中axios的使用
<head>
<script src="js/axios.min.js"></script>
<script src="js/vue.min.js"></script>
</head>
<body>
<div id="app">
axios.default.baseURL="http://localhost:5050"
Vue.prototype.axios=axios
new Vue({
el:'#app',
mounted(){
this.axios.get('/index').then(result=>{
console.log(result.data)
})
}
})
</div>
</body>
3. Ajax應該在哪個生命周期
- 有兩個選擇 created 和 mounted
- 推薦 mounted
原因
created階段鉤子函數(shù)已經(jīng)可以去讀取數(shù)據(jù),mounted階段鉤子函數(shù)組件已經(jīng)渲染完成,由于ajax請求是異步,當獲取到數(shù)據(jù)時,從beforeCreate到mounted已經(jīng)運行完了,所以在created和mounted發(fā)送請求都可以。
模擬操作
@/utils/data.js
function getData(){
return new Promise((resolve)=>{
setTimeout(()=>{
resolve(1000)
},2000)
})
}
export default getData
// home.vue
<div> {{count}} </div>
import getData from ../utils/data
export default{
async created(){
let result=await getData()
this.count=result
},
mounted(){
console.log('mounted')
},
activated(){
console.log('activated')
},
deactivated(){
console.log('deactivated')
},
updated(){
console.log(this.data)
},
//組件渲染完,狀態(tài)發(fā)生改變才會打印
//控制臺的update有打印,說明在mounted和created中發(fā)送請求獲取數(shù)據(jù)是在組件渲染之后,并且再一次更新dom樹。這也說明后臺獲取的數(shù)據(jù)無法做一次渲染
data(){
return{
count:100
}
}
}
4. 實際項目中封裝axios實例和請求方法的思路
- 在utils公共方法文件夾的request.js中
// 導入axios
import axios from 'axios'
// 創(chuàng)建axios實例
const service = axios.create({
// 公共接口--這里注意后面會講
baseURL: process.env.BASE_API,
// baseURL: '/api',
// 超時時間 單位是ms,這里設置了3s的超時時間
timeout: 10 * 1000
})
// 設置請求和響應的攔截器
service.interceptors.request.use(config => {},error=>{})
service.interceptors.response.use(response => {},error=>{})
- 在utils公共方法文件夾的http.js中導入axios實例
// 導入封裝好的axios實例
// 封裝 get put delete post請求方法
import request from './request'
const http = {
/**
* methods: 請求
* @param url 請求地址
* @param params 請求參數(shù)
*/
get (url, params) {
const config = {
method: 'get',
url: url
}
if (params) config.params = params
return request(config)
},
getData (url, data) {
const config = {
method: 'get',
url: url
}
if (data) config.data = data
return request(config)
},
post (url, params) {
const config = {
method: 'post',
url: url
}
if (params) config.data = params
return request(config)
},
put (url, params) {
const config = {
method: 'put',
url: url
}
if (params) config.params = params
return request(config)
},
delete (url, params) {
const config = {
method: 'delete',
url: url
}
if (params) config.params = params
return request(config)
}
}
export default http
- 在api文件夾的api.js中寫接口
import request from '@/utils/request'
import http from '@/utils/http'
// 兩種方式寫接口
// 舉例
// 登錄接口
export function login (data) {
return request({
url: 'api/logn',
method: 'post',
data: data,
})
}
// 首次任務開啟接口
export function startJob (id) {
return request({
url: 'api/jb/strt?factoryId='+id,
method: 'get'
})
}
// 同步任務接口
export function manualStartJob (param) {
return http.post('api/job/StartJob', param)
}
...
- 在組件中xxx.vue 使用封裝好的接口方法
import {login,startJob,manualStartJob} from './api/api'
vue項目中解決跨域問題
- 跨域的原因:瀏覽器同源策略
同源策略
著名的安全策略,注意:同源策略不是服務器行為,而是瀏覽器行為。
前端跨域報錯:
服務端解決跨域問題
- 上線需要使用nginx代理或者服務器配置cors(每中語言有自己得配置方式)
- 以nodejs的express框架為例:
npm i cors
let express=require('express')
let cors=requrie('cors')
let app=express()
app.listen(3000,()=>{
console.log('3000端口,已啟動')
})
// 配置跨域
app.use(cors,{
//允許跨域的服務器地址,可以寫多個
origin:['http://127.0.0.1:8080','http://localhost:8080']
})
vue項目實現(xiàn)跨域的原理
跨域是瀏覽器得安全策略,服務器和服務器之間發(fā)送請求沒有跨域,在啟動腳手架時會啟動一個內(nèi)置得web服務器,在請求時瀏覽器并沒有直接和需要請求得服務器通信,而是通過內(nèi)置得web服務器中轉。
注意:項目上線需要把打包后得文件放在服務器運行,而不是啟動腳手架運行,所以沒有內(nèi)置服務器中轉請求,此方式只適用于開發(fā)階段。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ooWbZ0TL-1683602902114)(https://note.youdao.com/yws/res/21666/WEBRESOURCE6ba5b29fcadfc7a73bef6dce6bae9ad2)]
@vue/cli4.5中處理
- 一般情況下如果需要使用低版本得腳手架,需要重新安裝腳手架
- 當然,npx 可以臨時創(chuàng)建一個目錄,使用4.5的腳手架
npx @vue/cli@4.5 create vue2
- 需要手動創(chuàng)建一個vue.config.js
modules.export={
devServer:{
// 配置代理服務器
proxy:{
//定義處理那種請求的開頭
//以后只要以/demo為開頭的請求,都會被處理
'/demo':{
// 往哪個服務器里發(fā)送請求
target:'http://127.0.0.1:3000',
pathRewrite:{
// ^代表字符串開頭,實際發(fā)送請求時把/demo替換成''
// 因為/demo并不是請求的一部分,只是代理的標識
'^/demo':''
}
}
}
}
}
@vue/cli5.0中處理
在vue腳手架中 5.0之后的版本會默認有vue.config.js文件,解決跨域問題需要在該文件中配置代理服務器
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer:{
//配置代理服務器
proxy:{
//定義處理那種請求的開頭
//以后只有是以/demo為開頭的請求,都會被處理
'/demo':{
//往哪個服務器發(fā)送請求
target:’http://127.0.0.1:3000’,
PathRewrite:{
//^代表字符串開頭,實際請求時把/demo替換成‘‘
// 因為/demo并不是請求得一部分,只是代理的標識
'^/demo':''
}
}
}
}
})
配置完后重啟腳手架生效…….
攔截器
VueRource 使用攔截器
文章來源:http://www.zghlxwxcb.cn/news/detail-774329.html
//cli
Vue.prototype.http=vueRource
Vue.http.interceptors.push((req,next)=>{
//請求發(fā)送前的處理邏輯
next((res)=>{
//請求發(fā)送后的處理邏輯
//res參數(shù)會返回給successCallback
//或 errorCallback
return res
})
})
//cdn
<div id="app"></div>
<script>
Vue.use(vueResource)
Vue.$http.interceptors.push((req,next)=>{
console.log('發(fā)送請求前攔截')
console.log(req)
next((res)=>{
console.log('收到響應結果后攔截')
console.log(res)
})
})
new Vue({
el:'#app'
data:{
...
},
methods:{
...
},
...
})
</script>
axios 使用攔截器
axios.interceptors.response.use文章來源地址http://www.zghlxwxcb.cn/news/detail-774329.html
import axios from 'axios'
var axios=axios.create() // 創(chuàng)建一個實例
axios.interceptors.request.use(config=>{ //請求攔截器
console.log('在發(fā)送請求前攔截...')
console.log(config)
return config
})
axios.interceptors.response.use(
res=>{ //響應攔截器
console.log(`在收到響應后攔截...`)
console.log(res)
return res
}
)
- 案例
/** ** request.js ****/
// 導入axios
import axios from 'axios'
import { message } from 'ant-design-vue'
// 1. 創(chuàng)建新的axios實例,
const service = axios.create({
// 公共接口--這里注意后面會講
baseURL: process.env.BASE_API,
// baseURL: '/api',
// 超時時間 單位是ms,這里設置了3s的超時時間
timeout: 10 * 1000
})
// 2.請求攔截器
service.interceptors.request.use(config => {
// 發(fā)請求前做的一些處理,數(shù)據(jù)轉化,配置請求頭,設置token,設置loading等,根據(jù)需求去添加
// config.data = JSON.stringify(config.data) // 數(shù)據(jù)轉化,也可以使用qs轉換
// config.data = config.data
config.headers = {
// 'Content-Type': 'application/x-www-form-urlencoded' // 配置請求頭
}
// 注意使用token的時候需要引入cookie方法或者用本地localStorage等方法,推薦js-cookie
// 這里取token之前,你肯定需要先拿到token,存一下
if (sessionStorage.getItem('session')) {
// config.headers['authorization'] = sessionStorage.getItem('session')
}
// config.withCredentials = true
return config
}, error => {
Promise.reject(error)
})
// 3.響應攔截器
service.interceptors.response.use(response => {
// 接收到響應數(shù)據(jù)并成功后的一些共有的處理,關閉loading等
if (response.data.code === 10000) {
message.error('用戶信息過期,請重新登錄')
window.localStorage.removeItem('sync-session')
window.sessionStorage.removeItem('sync-session')
location.href = ('/sync/#/')
}
return response
}, error => {
/** *** 接收到異常響應的處理開始 *****/
if (error && error.response) {
// 1.公共錯誤處理
// 2.根據(jù)響應碼具體處理
switch (error.response.status) {
case 400:
error.message = '錯誤請求'
break
case 401:
error.message = '未授權,請重新登錄'
break
case 403:
error.message = '拒絕訪問'
break
case 404:
error.message = '請求錯誤,未找到該資源'
// window.location.href = '/NotFound'
break
case 405:
error.message = '請求方法未允許'
break
case 408:
error.message = '請求超時'
break
case 500:
error.message = '服務器端出錯'
break
case 501:
error.message = '網(wǎng)絡未實現(xiàn)'
break
case 502:
error.message = '網(wǎng)絡錯誤'
break
case 503:
error.message = '服務不可用'
break
case 504:
error.message = '網(wǎng)絡超時'
break
case 505:
error.message = 'http版本不支持該請求'
break
default:
error.message = `連接錯誤${error.response.status}`
}
} else {
// 超時處理
if (JSON.stringify(error).includes('timeout')) {
message.error('服務器響應超時,請刷新當前頁')
}
error.message = '連接服務器失敗'
}
message.error(error.message)
/** *** 處理結束 *****/
// 如果不需要錯誤處理,以上的處理過程都可省略
return Promise.resolve(error.response)
})
// 4.導入文件
export default service
到了這里,關于簡述vue項目中的兩種請求方式(axios和vueResource)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!