已启用CORS仍遇403错误:无法访问Swagger YAML文件
问题描述
直接从本地Golang项目的swagger-ui文件夹打开UI界面,Swagger YAML文件托管在localhost:8080/swagger/#。已通过rs/cors中间件配置CORS,本地curl请求返回200状态码且预检请求头配置正常,但浏览器仍返回403错误。使用命令start chrome --disable-web-security --user-data-dir="C:\\chrome_dev"关闭浏览器安全设置后,请求可正常响应。相关代码如下:
package main import ( "context" "configurations" "utils" "flag" "log" "net/http" "os" "os/signal" "time" "github.com/gorilla/mux" "github.com/rs/cors" ) func main() { configs := configurations.conf(utils.CONFIG_FILE) r := mux.NewRouter().StrictSlash(true) createRoutes(r) cOpts := cors.Options{ AllowedOrigins: []string{"*"}, AllowedMethods: []string{"GET", "POST","PUT","OPTIONS","DELETE"}, AllowedHeaders: []string{"accept", "Origin", "Content-Type", "X-Requested-With"}, AllowCredentials: false, } corsHandler := cors.New(cOpts) srv := &http.Server{ Addr: configs.ThisPortNumber, Handler: corsHandler.Handler(r), } go func() { if err := srv.ListenAndServe(); err != nil { log.Println(err) } }() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c ctx, cancel := context.WithTimeout(context.Background(), wait) defer cancel() srv.Shutdown(ctx) configurations.PrintToLog(configurations.LogClassInformational, logRequestId, logFunctionFunctionName, "shutting down") os.Exit(0) }
解决方案
原因分析
直接打开本地文件时,页面的Origin为file://,rs/cors库默认对file:// Origin的匹配逻辑存在限制,即使设置AllowedOrigins: []string{"*"}也无法正常放行,导致浏览器触发403错误。
方案1:修改CORS配置,明确允许file:// Origin
修改cors.Options配置,添加自定义Origin校验函数,直接允许file://及本地开发相关Origin:
import "strings" // 需要额外引入strings包 // ... cOpts := cors.Options{ AllowedMethods: []string{"GET", "POST", "PUT", "OPTIONS", "DELETE"}, AllowedHeaders: []string{"accept", "Origin", "Content-Type", "X-Requested-With"}, AllowCredentials: false, // 自定义Origin校验逻辑 AllowOriginFunc: func(origin string) bool { // 允许file://、空Origin(部分浏览器本地文件的Origin为空)及localhost域名 return origin == "file://" || origin == "" || strings.HasPrefix(origin, "http://localhost") }, }
方案2:将swagger-ui托管到Golang服务(更推荐)
让Swagger UI页面与API服务同域,从根源上避免跨域问题。将swagger-ui的静态文件托管到Golang服务中:
// 在createRoutes(r)之后添加以下代码 // 假设swagger-ui文件夹位于项目根目录的swagger-ui子文件夹下 r.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", http.FileServer(http.Dir("./swagger-ui"))))
之后访问http://localhost:8080/swagger-ui/index.html即可打开Swagger UI,此时页面与API同域,无需额外CORS配置即可正常请求Swagger YAML文件。
内容的提问来源于stack exchange,提问作者Shiv Sree
相关产品推荐
相关产品推荐

