Vue axios与Go Frame后端框架的Options请求跨域问题详解


Posted in Javascript onMarch 03, 2020

跨域问题可从前后两端分开排查:

前端:Vue + axios

axios 请求头使用 'Content-Type': 'application/json',

并且在Header中设置了 Authorization 字段用于传递 Token,

参数未经 Qs 转码,

使用以下代码测试登录接口:

// 为方便操作,已将 axios 实例挂载到 this.$axios 上
this.$axios.post('/signin', {account: '', password: ''})
 .then(res => {
  console.log('成功:', res)
 })
 .catch(err => {
  console.log('失败: ', err)
 })

出现如下错误:

Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/v1/signin' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

同时 POST 请求变成了 OPTIONS 请求,并且返回404,如下图:

Vue axios与Go Frame后端框架的Options请求跨域问题详解

这里有两个问题,一个是为什么 POST 变成了 OPTIONS?URL 路径没错,为什么又会返回 404?

POST 变 OPTIONS 问题涉及复杂跨域请求,符合以下任意一个条件的请求就算复杂请求:

  1. 使用了除 HEAD、GET、POST之外的请求方法;
  2. 头部字段不超出 Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type,并且 Content-Type 的值只限于 application/x-www-form-urlencoded、multipart/form-data、text/plain;

由于设置的 Authorization 字段,Content-Type 也设置为了 application/json,因此这个请求算复杂跨域请求,会在正式通信前增加一次 OPTIONS 查询请求,称为"预检"请求(preflight request),用于向服务器请求权限等信息,预检请求被成功响应后,才会发出真实的 POST 请求。

可为什么 OPTIONS 请求返回 404 呢?
通过上面的错误说明及分析,答案应该很清晰了,就是服务端路由未对 OPTIONS 类型请求做出响应,导致 404 的情况。

后端:GoFrame

GoFrame 的路由代码如下:

func init() {
 s := g.Server()
 // 绑定 CORS 中间件
 s.BindMiddleware("/api/*", middleware.CORS)
 s.Group("/api", func(group *ghttp.RouterGroup) {
  ...
  // 重点:此路由仅支持 POST
  group.POST("/signin", userController, "SignIn")
 }
}

/signin 的路由指定了请求方式为 POST,自然无法响应其他类型的请求,使用如下方式定义倒是可响应所有类型的请求:

group.ALL("/signin", userController, "SignIn")

这样就使该路由支持所有的请求方法,但需要在控制器的 SignIn 方法中做判断需要响应哪些类型的请求,很繁琐,不推荐此方式。

其实只要在 CORS 中间件中对 OPTIONS 请求做统一响应即可,上代码:

// CORS 允许接口跨域请求
func CORS(r *ghttp.Request) {
 // 使用框架默认的 CORS 设置
 r.Response.CORSDefault()
 if r.Method == "OPTIONS" {
  r.Response.WriteStatusExit(http.StatusOK)
 } else {
  r.Middleware.Next()
 }
}

另外需要注意的是,使用 GoFrame 框架,CORS 中间件要在全局添加,如果在路由组中添加,同样会出现 OPTIONS 请求 404 的情况,而且中间件的代码在请求过程中未执行,原因暂不清楚,还需要多了解下框架。

本文描述的跨域问题是在网页上使用 Vue + axios 时出现的,使用 Postman 工具调试则一切正常,这里记录下排查过程和解决方法,希望能帮到有需要的童鞋,有任何问题可以在评论里一起讨论下。

到此这篇关于Vue axios与Go Frame后端框架的Options请求跨域问题详解的文章就介绍到这了,更多相关Vue axios与Go Frame跨域内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
[原创]来自ImageSee官方 JavaScript图片浏览器
Jan 16 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
Apr 26 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
Feb 02 Javascript
js基于cookie记录来宾姓名的方法
Jul 19 Javascript
Vue.js每天必学之方法与事件处理器
Sep 06 Javascript
ES6正则的扩展实例详解
Apr 25 Javascript
Centos6.8下Node.js安装教程
May 12 Javascript
Angular4自制一个市县二级联动组件示例
Nov 21 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
Jan 08 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
Jun 24 Javascript
基于vue手写tree插件的那点事儿
Aug 20 Javascript
vue ref如何获取子组件属性值
Mar 31 Vue.js
JS面向对象编程基础篇(一) 对象和构造函数实例详解
Mar 03 #Javascript
vue中改变滚动条样式的方法
Mar 03 #Javascript
vue倒计时刷新页面不会从头开始的解决方法
Mar 03 #Javascript
vuex(vue状态管理)的特殊应用案例分享
Mar 03 #Javascript
使用vue打包进行云服务器上传的问题
Mar 02 #Javascript
微信小程序scroll-view的滚动条设置实现
Mar 02 #Javascript
JS如何生成随机验证码
Mar 02 #Javascript
You might like
php的计数器程序
2006/10/09 PHP
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
ThinkPHP的L方法使用简介
2014/06/18 PHP
orm获取关联表里的属性值
2016/04/17 PHP
JavaScript CSS 修改学习第四章 透明度设置
2010/02/19 Javascript
jquery 跨域访问问题解决方法(笔记)
2011/06/08 Javascript
使用Chrome浏览器调试AngularJS应用的方法
2015/06/18 Javascript
jQuery中hover与mouseover和mouseout的区别分析
2015/12/24 Javascript
JavaScript禁止用户多次提交的两种方法
2016/07/24 Javascript
window.open打开窗口被拦截的快速解决方法
2016/08/04 Javascript
JavaScript数据类型学习笔记分享
2016/09/01 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
Vuex 使用及简单实例(计数器)
2018/08/29 Javascript
Python标准库内置函数complex介绍
2014/11/25 Python
Python选择排序、冒泡排序、合并排序代码实例
2015/04/10 Python
Python随机生成信用卡卡号的实现方法
2015/05/14 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
django 修改server端口号的方法
2018/05/14 Python
浅谈Python 多进程默认不能共享全局变量的问题
2019/01/11 Python
python实现DEM数据的阴影生成的方法
2019/07/23 Python
TensorBoard 计算图的可视化实现
2020/02/15 Python
Pytest参数化parametrize使用代码实例
2020/02/22 Python
Python smtp邮件发送模块用法教程
2020/06/15 Python
微软日本官方网站:Microsoft日本
2017/11/26 全球购物
如何写一个Java类既可以用作applet也可以用作java应用
2016/01/18 面试题
房地产融资计划书
2014/01/10 职场文书
校园公益广告语
2014/03/13 职场文书
聚美优品励志广告词
2014/03/14 职场文书
社区消防工作实施方案
2014/03/21 职场文书
小学节能减排倡议书
2014/05/15 职场文书
安全生产月标语
2014/10/07 职场文书
2014年办公室主任工作总结
2014/11/12 职场文书
社会治安综合治理责任书
2015/01/29 职场文书
请学会珍惜眼前,因为人生没有下辈子!
2019/11/12 职场文书
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python