跨域案例go gf ,请求代理,前端请求后端A转发给多个后端B

这篇具有很好参考价值的文章主要介绍了跨域案例go gf ,请求代理,前端请求后端A转发给多个后端B。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

跨域案例go gf ,请求代理,前端请求后端A转后端B

案例:从前端请求后端A(路径携带argusx),后端A转发请求到多个不同地区(可一个)后端B(切掉argusx,其他不变进行请求),由请求头x-proxy指定请求哪个服务端

方案一:handler形式处理:

func InitRouter() {
	s := g.Server()

	// 分组路由注册方式
	app.Api = s.Group("/argusx", func(group *ghttp.RouterGroup) {
		// 跨域中间件
		service.Middleware.InitGroup(group)
		ReverseProxy(group, "/xxx/")
	})
}

// InitGroup 注册中间件
func (s *middlewareService) InitGroup(group *ghttp.RouterGroup) {
	group.Middleware(
		// 跨域处理
		s.CORS,
		//s.Auth,
	)
}
// 使用默认跨域处理
func (s *middlewareService) CORS(r *ghttp.Request) {
	//r.Response.CORSDefault() //若是请求头没有新的,则直接用default,否则用下面三行代码
	options := r.Response.DefaultCORSOptions()
	options.AllowHeaders = options.AllowHeaders + ",X-Proxy"
	r.Response.CORS(options)
	r.Middleware.Next()
}
func ReverseProxy(pg *ghttp.RouterGroup, path string) {
	op := func(r *ghttp.Request) {
		// 根据code拿到地址,可用自己的方式获取参数
		argusvoiceCode := r.GetHeader("x-proxy")
		g.Log().Infof("[argusvoice] argusvoiceCode=%s", argusvoiceCode)
		if argusvoiceCode != "" {
			argusvoiceApi := service.GetArgusVoiceUrlByCode(argusvoiceCode)
			g.Log().Infof("[argusvoice] argusvoiceApi=%s", argusvoiceApi)
			remote, err := url.Parse(argusvoiceApi)
			if err != nil {
				fmt.Println(err.Error())
				g.Log().Errorf("[argusvoice] url parse error, argusvoiceApi=%s, error=%v", argusvoiceApi, err)
			}
			reverseProxy := proxy.GoReverseProxy(&proxy.RProxy{
				Remote: remote,
			})
			if err != nil {
				fmt.Println(err.Error())
				r.ExitAll()
				return
			}
			reverseProxy.ServeHTTP(r.Response.Writer, r.Request)
			r.ExitAll()
		} else {
			r.Middleware.Next()
		}
	}
	pg.Bind([]ghttp.GroupItem{{"ALL", path + "*", op}})
}

方案二:中间件的形式代理:
对所有请求都拦截,包括options,这样需要自己处理options请求,options请求是为了协商请求头,所以需要返回成功以及必要信息方便后期请求携带。
请求允许的加上x-proxy,注意option请求是拿不到具体的值
坏处:无法使用框架自带的options处理

s.BindMiddlewareDefault(func(r *ghttp.Request) {
	// 根据code拿到地址
	accessControlHeaders := r.Header.Get("Access-Control-Request-Headers")
	isProxy := strings.Contains(accessControlHeaders, "x-proxy")
	argusvoiceCode := r.GetHeader("x-proxy")
	r.Header.Set("Access-Control-Allow-Origin", "*")
	g.Log().Infof("[argusvoice] argusvoiceCode=%s", argusvoiceCode)
	if isProxy || (argusvoiceCode != "") {
		argusvoiceApi := service.GetArgusVoiceUrlByCode(argusvoiceCode)
		if r.Request.Method == "OPTIONS" {
			r.Response.Status = 200
			// 以下头部请参照自己正常请求的头部
			r.Response.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) //此处不能写作*
			r.Response.Header().Set("Access-Control-Allow-Credentials", "true")
			r.Response.Header().Set("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token, x-requested-with,Accept,Origin,Referer,User-Agent,x-proxy")
			r.Response.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE")
			r.Response.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
			return
		}
		g.Log().Infof("[argusvoice] argusvoiceApi=%s", argusvoiceApi)
		remote, err := url.Parse(argusvoiceApi)
		if err != nil {
			fmt.Println(err.Error())
			g.Log().Errorf("[argusvoice] url parse error, argusvoiceApi=%s, error=%v", argusvoiceApi, err)
		}
		reverseProxy := proxy.GoReverseProxy(&proxy.RProxy{
			Remote: remote,
		})
		if err != nil {
			fmt.Println(err.Error())
			r.ExitAll()
			return
		}
		reverseProxy.ServeHTTP(r.Response.Writer, r.Request)
		r.ExitAll()
	} else {
		r.Middleware.Next()
	}
})

proxy文件:(此处代码大部分抄自https://github.com/hezhizheng/go-reverse-proxy/blob/master/handle.go)
该项目使用案例:https://hzz.cool/blog/implementation-of-simple-http-and-https-reverse-proxy-by-golang文章来源地址https://www.toymoban.com/news/detail-683059.html

package proxy

import (
	"github.com/gogf/gf/frame/g"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
)

type RProxy struct {
	Remote *url.URL
}

func GoReverseProxy(this *RProxy) *httputil.ReverseProxy {
	remote := this.Remote

	proxy := httputil.NewSingleHostReverseProxy(remote)

	proxy.Director = func(request *http.Request) {
		Path := ""
		targetQuery := remote.RawQuery
		request.URL.Scheme = remote.Scheme
		request.URL.Host = remote.Host
		request.Host = remote.Host
		Path, request.URL.RawPath = joinURLPath(remote, request.URL)
		Paths := strings.Split(Path, "/argusx")
		request.URL.Path = Paths[1]
		g.Log().Infof("[argusvoice] request.Body=%v", request.Body)
		if targetQuery == "" || request.URL.RawQuery == "" {
			request.URL.RawQuery = targetQuery + request.URL.RawQuery
		} else {
			request.URL.RawQuery = targetQuery + "&" + request.URL.RawQuery
		}
		g.Log().Infof("[argusvoice] request.URL.Path=%s, request.URL.RawQuery=%s", request.URL.Path, request.URL.RawQuery)
	}
	proxy.ModifyResponse = func(response *http.Response) error {
		response.Header.Del("Access-Control-Allow-Origin")
		response.Header.Del("Access-Control-Allow-Credentials")
		response.Header.Del("Access-Control-Allow-Headers")
		response.Header.Del("Access-Control-Allow-Methods")
		return nil
	}
	return proxy
}

// go sdk 源码
func joinURLPath(a, b *url.URL) (path, rawpath string) {
	if a.RawPath == "" && b.RawPath == "" {
		return singleJoiningSlash(a.Path, b.Path), ""
	}
	// Same as singleJoiningSlash, but uses EscapedPath to determine
	// whether a slash should be added
	apath := a.EscapedPath()
	bpath := b.EscapedPath()

	aslash := strings.HasSuffix(apath, "/")
	bslash := strings.HasPrefix(bpath, "/")

	switch {
	case aslash && bslash:
		return a.Path + b.Path[1:], apath + bpath[1:]
	case !aslash && !bslash:
		return a.Path + "/" + b.Path, apath + "/" + bpath
	}
	return a.Path + b.Path, apath + bpath
}

// go sdk 源码
func singleJoiningSlash(a, b string) string {
	aslash := strings.HasSuffix(a, "/")
	bslash := strings.HasPrefix(b, "/")
	switch {
	case aslash && bslash:
		return a + b[1:]
	case !aslash && !bslash:
		return a + "/" + b
	}
	return a + b
}

到了这里,关于跨域案例go gf ,请求代理,前端请求后端A转发给多个后端B的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端vue后端go如何进行跨域设置?一篇就通透理解

    跨域 (Cross-Origin)指的是在 浏览器 中,当一个 web 应用程序试图访问 不同域名、不同端口或不同协议的资源时,就会发生跨域请求 ,此时浏览器的 同源策略 (Same-Origin Policy)就会进行拦截,他是同源策略是一种 安全机制 ,它限制了网页中的 JavaScript 代码只能访问同源(

    2024年04月12日
    浏览(33)
  • 百度语音识别(语音转文字)vue版本 前端(后端需要做个请求转发即可)

    这个项目需要用到语音识别,最后选择的是百度语音识别。原因第一是项目中用到的地方不大,属于微型和小型功能点,第二就是属于临时增加的需求,没有太多的时间去开发,第三就是后端对于自主开发语音识别觉得较为困难,浪费时间。 加载语音识别的文件 下载recorde

    2024年02月12日
    浏览(36)
  • Ruoyi-Vue处理跨域问题、同时请求多个域名接口(前端处理)

    Ruoyi-Vue项目请求不同地址的接口,主要在于处理跨域问题,即vue.config.js文件处理 1. 修改配置文件(.env.development/.env.production) 2. 修改vue.config.js文件 即新增一个代理。部署项目时, 如果使用nginx等代理方式,记得配置VUE_APP_API_SERVICE对应的路径及跳转地址 3. 新建requestNew.js文件

    2024年02月03日
    浏览(30)
  • 本地前端代理连接服务器后端gateway api浏览器提示cors跨域,如何解决?

    🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家 关注收藏订阅 !持续更新中,up!up!up!!   本地前端代理连接服务器后端gateway api浏览器提示

    2024年04月12日
    浏览(35)
  • 用Nginx将前端Vue项目部署到云服务器(含代理实现请求跨域)

    记录使用Nginx将 纯前端 的Vue3项目部署到阿里云服务器(Ubuntu 22.04)上,包含通过Nginx代理实现 跨域请求 、以及个人踩坑记录~ 执行下列命令安装: 安装完成后查看nignx版本,显示版本信息则说明安装成果 启动nginx,如正确启动,则不会出现任何提示信息。 nginx启动成功后打

    2024年04月12日
    浏览(33)
  • Nginx将请求转发至后端应该怎么做?

    在nginx的配置文件中新建一个server监听前端部署的端口 然后在server中添加一个location,就是把访问路径指向前端项目打包后的地址 在部署前后端分离项目时,通常都要使用nginx把前端的请求转发到后端的接口上去,这就要配置nginx的proxy_pass功能。 代理转发需要注意的事儿 在

    2024年02月04日
    浏览(37)
  • Caddy反向代理转发修改http请求路径

    Caddy是个非常不错的开源服务器产品,简单易用,自带ssl。只是没啥详细的中文文档,遇到问题只能看官方文档。 记录一下使用Caddy转发http请求的方法。 问题:将http://192.168.1.10:7077/product/*的请求转发到http://192.168.1.12:7078/*。这里其实是两个需求,一个是转发端口,还有个是去

    2024年02月12日
    浏览(33)
  • 1.10 springboot项目后端设置允许跨域请求

    一 . springboot项目中,后端设置允许跨域请求

    2024年02月16日
    浏览(24)
  • Netty服务如何使用Nginx代理转发请求并获得原始IP

    Nginx启用stream模块,示例如下: 示例,代理远端8080的netty服务。 注意,获得原始客户端的IP关键配置在于: proxy_protocol on; 这一行配置。如果不配置,在netty服务端是无法获得原始客户端ip,但是配置上之后,netty需要调整代码。 代理http协议的时候,可以通过增加X-Forwarded-Fo

    2024年02月06日
    浏览(35)
  • 服务器上一个域名对应多个前端项目的nginx转发配置

    场景: 当有两个前端项目A,B的时候,项目A(对应端口8000)和项目B(对应端口8001)分别部署在服务器的不同位置,通过服务器ip+端口都能正常访问单独的项目A和项目B;现在要求两个项目共用一个域名~~也就是说访问http://10.111.182.xxx:8000的时候默认访问项目A的资源,访问htt

    2024年02月05日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包