前言
本文基於vue-cli3
。
一、通過api接口獲取數據
在vuejs
中請求接口,大體分爲兩種方式:vue-source
和axios
。它們都是經過良好封裝的http請求插件。
下文將簡單介紹一下使用方法。
1. vue-source
略講,詳情見這篇博客。
安裝
首先,安裝該插件:
npm install vue-source --save
然後,在項目src/main.js
中,通過全局方法Vue.use()
使用該插件:
import VueSource from 'vue-source'
Vue.use(VueSource)
使用
在data中定義好接口和接收的數據類型,然後,調用this.$http.get()
函數進行get
請求即可,代碼如下:
data () {
return {
apiUrl: 'https://xxxxx',
users: []
}
},
methods: {
},
created () {
this.$http.get(this.apiUrl).then((response) => {
console.log(response)
}, (error) => {
console.log('error:', error)
})
}
代碼解釋:$http.get().then()是get函數請求返回後才調用的函數。then()函數的中兩個參數是匿名函數。上述代碼使用了ES6新增了箭頭函數(即參數指向函數),也可以寫成以下形式:
this.$http.get(this.apiUrl).then(function (response) {
console.log(response)
}, function (error) {
console.log('error:', error)
})
2. axios
安裝
npm install axios
使用
axios
庫的主要請求函數有:
axios.request(config)
axios.get(url[, config]) // 表示 axios.get(url, config) 和 axios.get(url) 都被允許
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
config
對象的詳細屬性、請求的後續then()/catch()
操作、配置的默認值/defaults等等,見 Axios 中文說明。
(以下純屬個人觀點
爲了更好地進行模塊間的解耦,在vue-cli3
構建的項目的src\
目錄下,創建api\
目錄,將項目所有需要進行的請求的配置封裝到該目錄下。
此處示例只封裝到一個api.js
文件,如下:
// src/api/api.js
import axios from 'axios'
// 允許跨域攜帶cookie
// axios.defaults.withCredentials = true;
export const uploadelf = () => {
return axios.request({
method: 'post',
url: 'http://xxxxx.xxx/api/uploadelf'
})
}
export const start = () => {
return axios.request({
method: 'get',
url: 'http://xxxxx.xxx/api/start'
})
}
export const getDisassemble = (funName = 'main') => {
return axios.request({
method: 'post',
url: 'http://xxxxx.xxx/api/disassemble',
data: {
funName
}
})
}
其中,每個函數返回一個調用請求後的對象,相當於設計模式中的工廠方法。
如此封裝的好處是,用戶使用時,並不需要知道某個請求的請求url
和請求方式。
當你需要在其它模塊中進行相應的請求時,只需要import
導入api.js
中相應的函數變量並調用即可,如:
// src/view/main.vue
...
<script>
// 導入相應的請求函數
import {uploadelf, start, getDisassemble} from '../api/api'
export default {
data() {
return {
assemb: []
}
},
methods: {
click_uploadelf() {
// 調用該工廠方法進行請求返回一個對象,再通過對象的then(), catch()方法進行後續操作
uploadelf().then(resp => {
console.log('uploadelf --->', resp.data);
}).catch(error => {
console.log(error);
});
},
click_start() {
start().then(resp => {
console.log('start --->', resp.data);
}).catch(error => {
console.log(error);
});
},
click_getDisassemble() {
getDisassemble('main').then(resp => {
console.log('getDisassemble --->', resp.data);
this.assemb = resp.data.message;
}).catch(error => {
console.log(error);
});
}
}
}
</script>
補充
js
的請求屬於異步操作(不需要等請求完成,函數直接執行結束)。所以,需要通過回調函數來實現請求完成的後續操作。
axios
主要利用ES6 Promise
來實現異步請求的後續操作。
同時,異步請求會導致請求並行的情況。多個請求之前不能太接近。
二、跨域問題
1.問題
如果是本機localhost:8000測試,可能會出現跨域問題,打開瀏覽器會看到如下報錯:
跨域問題.png
2.補充
-
當兩個域具有相同的協議(如http), 相同的端口(如80),相同的域名如
www.baidu.com
,那麼我們就可以認爲它們是在相同的域中(協議,域名,端口都必須相同)。 -
跨域,就是指協議、域名、端口其中一個或多個不一致的情況下,從當前域去訪問另一個域。
-
出於安全考慮(防止跨域攻擊 XSS、CSRF),瀏覽器會禁止跨域的請求訪問。其實,同源策略是一種約定,它也是瀏覽器最核心也最基本的安全功能。
3.解決
跨域問題解決有很多方式,以下主要講兩種。
CROS(跨域資源共享)
前端Vue,設置axios
允許跨域帶cookie
(默認不帶cookie),如下:
// axios全局配置,允許跨域帶cookie
axios.defaults.withCredentials = true;
後端:
跨域請求後的響應頭中需要設置:
-
Access-Control-Allow-Origin
爲發起請求的主機地址。 -
Access-Control-Allow-Credentials
,當它被設置爲true
時,允許跨域帶cookie
,但此時Access-Control-Allow-Origin
不能爲通配符*
。 -
Access-Control-Allow-Headers
,設置跨域請求允許的請求頭。 -
Access-Control-Allow-Methods
,設置跨域請求允許的請求方式。
Vue代理
vue-cli
自帶代理功能,由node
服務器實現。
在項目根目錄下新增vue.config.js
項目配置文件,然後配置代理:
// 修改配置後一定要 重新npm run serve !!!
module.exports = {
devServer: {
// vue項目啓動時的ip地址和端口
host: 'localhost',
port: 8000,
proxy: {
// 匹配所有以 /api 開頭的url
'/api': {
// 請求的目標主機
target: 'http://dev3.airdb.io:8080',
changeOrigin: true,
ws: true
// 這樣重寫會把路徑中 /api 消去
// pathRewrite: {
// '^/api': '/api'
// }
}
}
}
}
設置代理後,本地nodejs
服務器會將目標主機的url
代理到vue
項目的url
。
如:
訪問http://dev3.airdb.io:8080
,會轉變成訪問http://localhost:8080
,再由http://localhost:8080
轉發請求到http://dev3.airdb.io:8080
。
這樣,就成了同域請求,瀏覽器不會進行限制。但實際上,還是請求了目標主機,只是欺騙了瀏覽器。
由於Vue代理需要利用node
服務器,所以只適用於本地npm run serve
調試時。
當項目部署到服務器時,可以使用CROS
方式、nginx
反向代理等方式。
nginx反向代理
只需要在nginx.conf
配置文件的vue
項目對應的server
中,添加:
# 匹配vue項目中所有以/api開頭的請求url
location /api {
include uwsgi_params;
proxy_pass http://0.0.0.0:8081; # 要代理訪問的後端url
}
完整示例如下:
server {
listen 8000;
listen 80;
server_name _;
root /pathto/vue_project/;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
index index.html;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
location /api {
include uwsgi_params;
proxy_pass http://0.0.0.0:8081;
}
}
作者:dounine
鏈接:https://www.jianshu.com/p/e935a8f81971
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。