Electron + Vue + Vscode构建跨平台应用(一)知识点补充
Electron + Vue + Vscode构建跨平台应用(二)Electron + Vue环境搭建
Electron + Vue + Vscode构建跨平台应用(三)利用webpack搭建vue项目
Electron + Vue + Vscode构建跨平台应用(四)利用Electron-Vue构建Vue应用详解
Electron + Vue + Vscode构建跨平台应用(五)Electron-Vue项目源码分析
Electron + Vue跨平台应用(六)效果还不错的登录页面
Electron + Vue跨平台应用(七)基础技法(一)
这篇主要对如下内容做个解答
- 什么是同源策略
- Axios的跨域代理配置
- Axios中Payload,FormData,Query String Parameters的配置处理
- Vue的配置文件中的proxyTable
- Vue中如何通过代码绑定样式
同源策略是一种约定,它是浏览器最核心也最基本的安全功能,同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制
1)同源的定义: 如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源
2)如何允许跨源访问: 使用 CORS (Cross-origin resource sharing,跨域资源共享)允许跨源访问,CORS是一个 W3C 标准,定义了浏览器与服务器应该如何沟通。CORS 背后的基本思想,就是使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
3)非同源访问会报什么错: no access-control-allow-origin header is present
4)为什么会发生这种情况
当前端发起一个请求到服务器的时候,服务端会检测是否允许进行跨域访问,即服务端是否配置了Access-Control-Allow-Origin
当配置为 * 的时候,代表任何请求都可以进行跨域访问,但是如果设置为 * 的话,游览器将不会发送cookies,即使后端XHR设置了withCredentials,或者前端axios设置了withCredentials;所以我们一般指定Access-Control-Allow-Origin为某一个host,这样就好了,如下
Access-Control-Allow-Origin:http://172.20.0.206
已实际开发为例,假设前端需要post一个请求,url为:“http://139.123.2.30:56980/app/getBacthInfo”
显然在前端调试的时候,前端浏览器和getBactchInfo接口不在一个源里面,必然会出现非同源拒绝访问的错误,这个时候我们就需要配置一下跨域访问,其步骤如下
1)打开Vue项目config目录下面的index.js文件,你会发现一个proxyTable的配置选项,这个选项就是跨域配置的重点,我们针对上面的url做如下配置
代码如下:
proxyTable: {
'/api':{
target: "http://139.123.2.30:56980",
changeOrigin:true,
pathRewrite:{
'^/api':''
}
}
第2行,表示每次发请求的时候都会带上一个/api的前缀,这个名字随意写,我们在调用接口的时候,就可以全局使用‘/api’,这时候‘/api’的作用就相当于‘http://139.123.2.30:56980’,比如接口的地址是‘http://139.123.2.30:56980/user/info’,我们就可以使用‘/api/user/info’
第3行,配置前端访问host,这里只写host就好,因为每个接口名是不一样的,且不需要带反斜杆
第4行,设置为true表示开启代理
第5行,顾名思义就是地址重写,相当于是替代‘/api’,如果接口中是没有api的,那就直接置空;如果接口中有api,那就得写成{‘^/api’:‘/api’},可以理解为一个重定向或者重新赋值的功能
2)当第一步配置好跨域处理之后,我们就可以着手写自己的Axios发送框架了,在写Axios框架的时候我们需要注意如下的配置
设置Axios的baseURL为proxyTable中的api
Axios.defaults.baseURL = '/api'
下面是我自己封装的Axios的post和get方法,其所在文件名为:httpclient.js
// 通用网络处理类
const Axios = require('axios')
Axios.defaults.baseURL = '/api'
Axios.interceptors.response.use(
response => {
let { data: resp } = response
return new Promise((resolve, reject) => {
const { code } = resp
code === '0' ? resolve(resp.data) : reject(resp)
})
},
error => {
return Promise.reject(error)
}
)
function get (url, data) {
return new Promise((resolve, reject) => {
Axios(url, {
// withCredentials: true,
// params: data
}).then(response => {
resolve(response)
}).catch(response => {
reject(response)
})
})
}
function post (url, data = {}, header = {}, method = 'post') {
return new Promise((resolve, reject) => {
Axios({
url: url,
method: method,
headers: header,
data: data
})
.then(res => {
resolve(res.data)
})
.catch(res => {
reject(res)
})
})
}
export default {
getApprovelList: post,
getlist: get
}
第3行:配置Axios的baseURL ,这样发出去的请求就会用proxyTable里面的target的值去替换你的url
第5行:配置响应拦截
第7行:通过解构完成对象赋值
第18行: 定义get方法
第30行: 定义post方法
上面的就是一个简单的网络收发框架
3)当定义好收发框架之后,就可以使用框架中的API了,比如我们在charge.vue中使用
<template>
<div>
</div>
</template>
<script>
import HttpClient from '@/utils/httpclient'
export default {
components: {
HttpClient
},
data () {
return {
this.queryType: '0'
}
},
mounted () {
this.getChargeList()
},
methods: {
getChargeList () {
let params = `currPage=1&pageSize=300&subcpCode=&mobaihejurisdiction=2&jcwj=&billflag=&spcode=&tablecode=000101&batchcode=&servtype=&SUBCP_AUTH=6&pageType=${this.queryType}`
HttpClient.getApprovelList('jsjmg/app/audit/getBacthInfo', params, {})
.then(res => {
})
.catch(() => {
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
</style>
第18行,在charge.vue加载的时候发送post方法,此时我们通过浏览器开发模式可以看到请求已经发送成功了
我们观察下1和2这两处
关于标记1处: 可以发现请求发起已localhost/8080/api的方式,通过上面的分析我们应该知道这个api会被转为proxytable的target的值
关于标记2处: 我们在上面的网络收发框架中,并没有对header的contenttype做特殊处理,其content-type默认为application/x-www-form-urlencoded;其携带数据的方式为FormData
在进行网络请求的时候,当请求携带参数的时候有的时候已FormData形式存在,有的是以Payload形式存在,有的时候以Query String Parameters形式存在。我们首先得弄清楚如下知识点
1)当Content-Type设置为application/x-www-form-urlencoded即默认的时候,post请求携带的参数会以FormData的形式存在,参数以&符号拼接,参数格式为key=value&key=value&key=value…
2)当Content-Type设置为application/json或者multipart/form-data的时候,post请求携带的参数会已Payload的形式存在,参数格式为JSON格式:{“key”:“value”,“key”:“value”…}
3)你也会发现有时参数会以如下形式发送,
其实就是请求中url后面要带的参数,即?后的字符串则为其请求参数,并以&作为分隔符
proxyTable使用的是http-proxy-middleware组件,其链接为http-proxy-middleware
<div id="app">
<button class="btn" :style="styles">点击我吧,主人!</button>
</div>
第2行,通过styles属性来对button进行样式绑定,当然你也可以通过方法来进行绑定,这个方法有返回值即可
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
styles: {
color: 'white',
backgroundColor: 'blue'
}
}
});
</script>