• Axios中每次发送post请求前都会发送options请求


    今天写前端的时候,发现每次post请求都会失败, 反复调试过后发现axios在每次发送post请求前都发送了options请求, 在网络搜罗了一大圈, 发现了原因是因为web页面发送了请求给vue后, vue再请求后端过程中发生了跨域, 而我使用的不是默认的跨域允许请求头, 而是content-type: application/json, 所以浏览器认为跨域即是不可靠行为, 所以每次都需要发送options请求, 进行跨域检测, 所以导致了每次options请求失败了, 所以post请求就没有下文了。

    问题来了, 之前我也用vue+axios写了前端, 为什么不会出现这样的情况呢? 

    首先我以为是配置的问题, 把axios拦截器里面的content-type改成了application/x-www-form-urlencoded, 结果发现确实不会再options的, 但是之前用的时候, 也跨域了, 但是却没有出现options。

    然后我以为是axios的版本问题, 就把axios从1.6.5降到了之前写的时候的1.6.2, 结果发现问题依旧,说明问题和版本无关。

    然后就想到了, 问题是基于跨域引起的, 那是不是因为后端没有设置跨域呢? 但是之前用Django写的后台也没有带跨域设置, Goframe应该也不用才对?

    抱着试一试的态度, 搜索了下GoFrame怎么设置跨域, 其实很简单, GoFrame已经帮我们做了封装, 在中间件中加入一个允许跨域的方法就行了。

    1. func MiddlewareHandlerResponse(r *ghttp.Request) {
    2. r.Response.CORSDefault()
    3. r.Middleware.Next()
    4. }

    然后在你的cmd中加入中间件即可

    1. var (
    2. Main = gcmd.Command{
    3. Name: "main",
    4. Usage: "main",
    5. Brief: "start http server",
    6. Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
    7. s := g.Server()
    8. s.Use(MiddlewareHandlerResponse)
    9. s.Group("/api", func(group *ghttp.RouterGroup) {
    10. group.Group("/v1", func(group *ghttp.RouterGroup) {
    11. group.Bind(hb.NewV1())
    12. })
    13. })
    14. s.Run()
    15. return nil
    16. },
    17. }
    18. )

    然后再次进行尝试, 问题解决了。

    仔细对照了一下, 后端加入了跨域后, 响应头多了如下几个请求头

    也就是多了一些允许跨域的设置, 这也是GoFrame帮忙封装的, 并且在源码中, 我们可以看到它针对OPTIONS请求都做了处理的。

    1. func (r *Response) CORS(options CORSOptions) {
    2. if r.CORSAllowedOrigin(options) {
    3. r.Header().Set("Access-Control-Allow-Origin", options.AllowOrigin)
    4. }
    5. if options.AllowCredentials != "" {
    6. r.Header().Set("Access-Control-Allow-Credentials", options.AllowCredentials)
    7. }
    8. if options.ExposeHeaders != "" {
    9. r.Header().Set("Access-Control-Expose-Headers", options.ExposeHeaders)
    10. }
    11. if options.MaxAge != 0 {
    12. r.Header().Set("Access-Control-Max-Age", gconv.String(options.MaxAge))
    13. }
    14. if options.AllowMethods != "" {
    15. r.Header().Set("Access-Control-Allow-Methods", options.AllowMethods)
    16. }
    17. if options.AllowHeaders != "" {
    18. r.Header().Set("Access-Control-Allow-Headers", options.AllowHeaders)
    19. }
    20. // No continue service handling if it's OPTIONS request.
    21. // Note that there's special checks in previous router searching,
    22. // so if it goes to here it means there's already serving handler exist.
    23. if gstr.Equal(r.Request.Method, "OPTIONS") {
    24. if r.Status == 0 {
    25. r.Status = http.StatusOK
    26. }
    27. // No continue serving.
    28. r.Request.ExitAll()
    29. }
    30. }

  • 相关阅读:
    介绍下我的知识星球
    学习pytorch7 神经网络的基本骨架--nn,module的使用
    测试老鸟整理,Postman加密接口测试-Rsa/Aes对参数加密(详细总结)
    【数据结构】树链剖分 (图文代码详解)
    PDFBOX和ASPOSE.PDF
    Apollo预测模块启动及调试
    14:STM32-----看门狗
    Jmeter脚本参数化和正则匹配
    【服务器数据恢复】ext3文件系统下硬盘坏道掉线的数据恢复案例
    基于NIFI工具搭建生产级别的IIOT系统
  • 原文地址:https://blog.csdn.net/willluckysmile/article/details/136574123