当前位置: 首页 > wzjs >正文

可以做项目的网站武汉网站维护公司

可以做项目的网站,武汉网站维护公司,广州番禺最新头条消息,2014最准六肖网站建设一、跨域(CORS)是什么? 跨域,指的是浏览器出于安全限制,前端页面在访问不同源(协议、域名、端口任一不同)的后端接口时,会被浏览器拦截。 比如: 前端地址后端接口地址是…

一、跨域(CORS)是什么?

跨域,指的是浏览器出于安全限制,前端页面在访问不同源(协议、域名、端口任一不同)的后端接口时,会被浏览器拦截。
比如:

前端地址后端接口地址是否跨域
http://a.comhttp://a.com/api
http://a.comhttps://a.com/api是(协议不同)
http://a.comhttp://b.com/api是(域名不同)
http://a.com:8080http://a.com:8090/api是(端口不同)

浏览器会进行CORS检查。如果后端没有正确返回Access-Control-Allow-*的HTTP头信息,浏览器就会阻止前端访问。


二、浏览器的跨域流程

  1. 简单请求(Simple Request)

    • 请求方法限定:GET、POST、HEAD
    • Content-Type仅限于:application/x-www-form-urlencoded、multipart/form-data或text/plain
    • 没有对头部进行修改(如果修改,则是预检请求
  2. 预检请求(Preflight Request)

    • GET、POST、HEAD的请求方法
    • Content-Type为application/json等非简单值
    • 包含自定义头部字段

三、后端怎么处理跨域?

  • 常见跨域解决方案:CORS(跨源资源共享):W3C标准,服务端设置响应头实现

    • 处理跨域,就是要在HTTP响应中加上几个头:
  • Access-Control-Allow-Origin:允许访问的源(如*或https://example.com)

  • Access-Control-Allow-Methods:允许的HTTP方法(如GET, POST等)

  • Access-Control-Allow-Headers:允许的请求头字段

  • Access-Control-Allow-Credentials:是否允许发送Cookie(true/false)

  • Access-Control-Max-Age:预检请求缓存时间(秒)

CORS请求流程:

  1. 浏览器检测到跨域请求,自动添加Origin头
  2. 服务器检查Origin,决定是否允许并设置CORS响应头
  3. 对于预检请求,先发送OPTIONS请求确认权限
  4. 浏览器根据响应头决定是否允许实际请求

四、在 Go 后端怎么处理跨域?

这里讲两个框架:

1. 在 gin 框架中处理跨域

方法一:自己写中间件(不推荐)
func CorsMiddleware() gin.HandlerFunc {return func(c *gin.Context) {c.Writer.Header().Set("Access-Control-Allow-Origin", "*") // 允许所有域c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")// 处理预检请求if c.Request.Method == "OPTIONS" {c.AbortWithStatus(204)return}c.Next()}
}

然后在main.go注册:

r := gin.Default()
r.Use(CorsMiddleware())

方法二:使用第三方库(推荐)

参考go文档:https://pkg.go.dev/github.com/gin-contrib/cors

用成熟的库,比如github.com/gin-contrib/cors

go get github.com/gin-contrib/cors

代码:

import "github.com/gin-contrib/cors"// Cors 创建并返回一个gin.HandlerFunc处理程序,用于配置跨域资源共享(CORS)。
// 该函数通过调用cors.New并传递一个cors.Config结构体来实现,该结构体包含了CORS的配置信息。
// 主要目的是为了允许来自任何源的请求(AllowAllOrigins: true),并指定允许的HTTP请求头和方法,
// 同时支持凭证的跨域请求(AllowCredentials: true)。
func Cors() gin.HandlerFunc {return cors.New(cors.Config{// AllowAllOrigins: true 表示允许来自所有域的请求。AllowAllOrigins: true,// AllowHeaders 指定了允许的请求头,包括Origin, Content-Length, Content-Type和Authorization。AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization",},// AllowMethods 指定了允许的HTTP方法,包括GET, POST, PUT, DELETE, HEAD和OPTIONS。AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS",},// ExposeHeaders 指定了允许被访问的响应头,包括Content-Length, Access-Control-Allow-Origin,// Access-Control-Allow-Headers, Cache-Control, Content-Language和Content-Type。ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Cache-Control", "Content-Language", "Content-Type",},// AllowCredentials: true 表示允许跨域请求带上用户凭证。cookiesAllowCredentials: true,})
}

main.go

r := gin.Default()
r.Use(middleware.Cors(), middleware.Auth()) // 这里可以抽象到routers.go 不过要注意中间件注册一定要在路由分组之前,因为这里的注册操作相当于给所有的URL设定cors规则,前后顺序不能颠倒

r.Use()是给之后所有注册的路由挂载这个中间件。
也就是说,如果你先注册了路由,再r.Use(),那些已经注册了的路由就不会受到新的中间件的影响。
简单讲:中间件只保护在它后面注册的路由。


2. 在 go-zero 框架中处理跨域

go-zero默认就带跨域处理,只要你在服务配置里面加上跨域设置。

比如etc/your-api.yaml配置文件中,写:

Name: your-api
Host: 0.0.0.0
Port: 8888
Cors: true

注意这个Cors: true,加了以后,go-zero框架自动帮你处理CORS,包括预检请求(OPTIONS)!

如果要自定义,比如允许指定源,可以在自定义中间件里处理。

也可以自己写中间件(不推荐,go-zero已经做了)
func CorsMiddleware() func(http.Handler) http.Handler {return func(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {w.Header().Set("Access-Control-Allow-Origin", "*")w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")if r.Method == "OPTIONS" {w.WriteHeader(http.StatusNoContent)return}next.ServeHTTP(w, r)})}
}

注册:

server := rest.MustNewServer(c, rest.WithMiddlewares([]rest.Middleware{CorsMiddleware(),}...,
))

不过一般没必要,直接开Cors: true就行。


五、常见问题

  • OPTIONS请求后端返回404
    ➔ 需要后端显式处理OPTIONS方法,比如返回204 No Content。
  • 跨域时前端带了cookie但失败
    ➔ 需要Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能是*,必须指定具体域名。
  • 前端提示No ‘Access-Control-Allow-Origin’ header is present
    ➔ 后端没返回CORS头,检查中间件是否正确加载。

六、总结

  • 跨域是浏览器安全机制;
  • 处理跨域主要是设置HTTP响应头;
  • gin自己可以写中间件或用gin-contrib/cors
  • go-zero直接在配置里加Cors: true
  • OPTIONS预检请求一定要处理,否则请求直接失败。

七、针对go-zero中使用跨域使用方案拓展

  1. main.go方案
server := rest.MustNewServer(c.RestConf,rest.WithCustomCors(func(header http.Header) { // 1.这是自定义跨域逻辑var allowOrigin = "Access-Control-Allow-Origin"var allOrigins = "http://localhost:5173"var allowMethods = "Access-Control-Allow-Methods"var allowHeaders = "Access-Control-Allow-Headers"var exposeHeaders = "Access-Control-Expose-Headers"var methods = "GET, HEAD, POST, PATCH, PUT, DELETE, OPTIONS"var allowHeadersVal = "xxxx, Content-Type, Origin, X-CSRF-Token, Authorization, AccessToken, Token, Range"var exposeHeadersVal = "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers"var maxAgeHeader = "Access-Control-Max-Age"var maxAgeHeaderVal = "86400"header.Set(allowOrigin, allOrigins)header.Set(allowMethods, methods)header.Set(allowHeaders, allowHeadersVal)header.Set(exposeHeaders, exposeHeadersVal)header.Set(maxAgeHeader, maxAgeHeaderVal)}, func(w http.ResponseWriter) {}),)defer server.Stop()// 2.简单跨域//server := rest.MustNewServer(c.RestConf,//	rest.WithCors("http://localhost:5173"))// 3.自定义头 (预检请求)//server := rest.MustNewServer(c.RestConf,//	//顺序不能颠倒//	rest.WithCors("http://localhost:5173"),//	rest.WithCorsHeaders("xxxx"),//)

  1. 在 internal/middleware 目录下创建 cors.go 文件
package middlewareimport ("net/http"
)// Cors 中间件处理跨域请求
func Cors(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {// 1. 设置允许访问的源// 生产环境应替换为具体的域名,如 "https://example.com"w.Header().Set("Access-Control-Allow-Origin", "*")// 2. 设置允许的HTTP方法w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")// 3. 设置允许的请求头w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")// 4. 设置是否允许发送Cookie等凭证信息// 如果设置为true,则Access-Control-Allow-Origin不能为*w.Header().Set("Access-Control-Allow-Credentials", "false")// 5. 设置预检请求缓存时间(秒)w.Header().Set("Access-Control-Max-Age", "86400")// 6. 如果是OPTIONS方法(预检请求),直接返回204if r.Method == "OPTIONS" {w.WriteHeader(http.StatusNoContent)return}// 7. 继续处理后续中间件和路由next.ServeHTTP(w, r)})
}

在 main 函数中使用中间件

package mainimport ("flag""fmt""xxx/internal/config""xxx/internal/handler""xxx/internal/middleware" // 引入中间件包"xxx/internal/svc""github.com/zeromicro/go-zero/core/conf""github.com/zeromicro/go-zero/rest"
)var configFile = flag.String("f", "etc/xxx-api.yaml", "the config file")func main() {flag.Parse()// 1. 加载配置文件var c config.Configconf.MustLoad(*configFile, &c)// 2. 创建服务上下文ctx := svc.NewServiceContext(c)// 3. 创建服务实例server := rest.MustNewServer(c.RestConf)defer server.Stop()// 4. 注册CORS中间件(关键步骤)server.Use(middleware.Cors)// 5. 注册路由处理器handler.RegisterHandlers(server, ctx)// 6. 打印启动信息并启动服务fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)server.Start()
}

https://github.com/0voice

http://www.dtcms.com/wzjs/222503.html

相关文章:

  • 贵州网站建设seo如何创建自己的网站
  • 网站开发和app开发的区别西安企业seo
  • 云浮市哪有做网站的搜多多搜索引擎入口
  • 潍坊路通工程建设有限公司网站苏州关键词seo排名
  • 如何用手机建立网站千锋教育培训收费一览表
  • 网站vr用什么做微信朋友圈广告推广
  • dw做的网站链接不会跳转枸橼酸西地那非片是什么
  • 可做推广的网站快速网站推广公司
  • 推广 电子商务网站建设磁力岛
  • 光谷网站开发电子邮件营销
  • 把网站做静态化百度资源站长平台
  • 公司网站维护费大概需要多少赣州网站seo
  • wordpress站点地图无法读取网络促销方案
  • 山东振国网站建设网站流量排行
  • 能力天空的网站建设优劣势以服务营销出名的企业
  • 网站建设 运维 管理包括网络服务网络推广
  • 吴江网站设计酒店营销策划与运营
  • 音乐网站建设的目的免费b站推广网站入口202
  • 中国制造网网站建设的优势sem 优化价格
  • app对接网站登录要怎么做seo排名如何优化
  • 大鹏教育平面设计官网优化网络培训
  • 浚县网站建设处理事件seo软件
  • 网站seo新手百度账号注册平台
  • 珠海左右创意园网站开发青岛网站关键词优化公司
  • 企业建站套餐百度推广助手下载
  • 网站被屏蔽怎么访问企业网站建设公司
  • 深圳微商城网站制作价格站长工具 站长之家
  • 武汉网站设计的学校网站模版
  • 深圳大簇激光公司网站互联网营销师怎么报名
  • 常州做企业网站怎么推广游戏叫别人玩