关于跨域,网上讲得很多,具体实施起来大多讲的不详细,贴我的vue端代码
require('es6-promise').polyfill()
import fetch from 'isomorphic-fetch'
const tokenstr = '保密'
/**
* post请求
* @param {String} options.url api地址
* @param {String} options.querydata querydata参数
* @return {Promise} Promise
*/
const _fetch = ({ url, querydata }, commit) => {
if (commit) commit('START_LOADING')
let _url = `http://127.0.0.1:88/v1${url}`
return fetch(_url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + tokenstr
},
body: querydata
})
.then((res) => {
if (commit) commit('FINISH_LOADING')
if (res.status >= 200 && res.status < 300) {
return res.json()
}
return Promise.reject(new Error(res.status))
})
}
主要是服务端,我的服务端用的是golang的beego框架。
//跨域 func (c *BaseController) AllowCross() { c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "http://localhost:8080") //允许访问源 c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS") //允许post访问 c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Headers", "Content-Type,Authorization") //header的类型 c.Ctx.ResponseWriter.Header().Set("Access-Control-Max-Age", "1728000") c.Ctx.ResponseWriter.Header().Set("Access-Control-Allow-Credentials", "true") c.Ctx.ResponseWriter.Header().Set("content-type", "application/json") //返回数据格式是json }
这里在BaseController中写过函数,其它Controller函数继承BaseController,并在每个方法中调用下这个函数。
另外,由于我的header用了 ‘Authorization’,这样属于复杂请求,对于复杂请求,浏览器会自动先发一个options请求,那么在后端路由中也需要加这个options请求的路由,(如果不是用框架,就直接判断请求类型)
beego.NSNamespace("/*", //Options用于跨域复杂请求预检 beego.NSRouter("/*", &v1.BaseController{}, "options:Options"), ),
BaseController中加入Options的处理方法,(事实上Options返回的内容是啥一点也不重要)
func (c *BaseController) Options() { c.AllowCross() //允许跨域 c.Data["json"] = map[string]interface{}{"status": 200, "message": "ok", "moreinfo": ""} c.ServeJSON() }