一个利用go反向代理解决api转发的例子(go反向代理)
实现的效果:
如果访问的url路径是类似 /163/ 或 /163/debian 的形式,则转发到163开源镜像服务器
直接上代码:
package main import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
) var fwdHost = "mirrors.163.com" //http首部字段的HOST取值
var fwdTo = "http://" + fwdHost + "/"
var fwdPrefix = "/163/" type forward struct {
RProxy *httputil.ReverseProxy
} func (f *forward) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
//fmt.Printf("http头部是:%+v\n", req.Header) //假设这是处理http头部的代码
fmt.Printf(" #### REQ:%+v\n", req) //处理完后转发到网易163镜像
req.URL.Path = req.URL.Path[len(fwdPrefix)-1:] //修改了这里,req.RequestURI会跟着变
req.Host = fwdHost
fmt.Printf(" *** REQ:%+v\n", req)
f.RProxy.ServeHTTP(wr, req)
} func main() {
var fwd forward
u, _ := url.Parse(fwdTo)
fwd.RProxy = httputil.NewSingleHostReverseProxy(u)
http.Handle(fwdPrefix, &fwd) //所有请求将转发到网易163的debian镜像
http.HandleFunc("/", notForward)
http.HandleFunc("/api/v1/", notForward)
log.Fatal(http.ListenAndServe(":3000", nil))
} func notForward(wr http.ResponseWriter, req *http.Request) {
wr.Write([]byte(fmt.Sprintf(`<html>
<body>
<em>Not forward!!</em>
<br />
<i>url = %s</i>
</body>
</html>
`,req.URL.String())))
}
类似的还有更简单的做法,关键在httputil.ReverseProxy的Director字段:
func APIReverseProxy(host string) http.HandlerFunc {
var rp = httputil.ReverseProxy{
Director:func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = host
req.Host = host //对于一个ip地址托管多个域名的情况下,必须要给req.Host赋值,如果一个ip地址只有一个域名,可以不写这一句
//req.URL.Path = //如果需要改path的话
},
}
return func(wr http.ResponsWriter, req *http.Request){
rp.ServeHTTP(wr,req)
} //这里是返回http.HandlerFunc的例子,其实也可以直接返回rp(因为*rp就是一个http.Handler, *rp实现了ServeHTTP(wr,req)方法)
}
关于req.URL.Host和req.Host:
go http包中对request中Host的注释:
// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
另外:
req.URL.Host是从URL中解析出来的,
req.Host是http请求头部"Host" , 这个头部用于实现虚拟主机(一个ip托管多个域名),http1.1规范中,Host头是必须存在的
对于下面的请求:
GET /index.html HTTP/1.1
Host: www.example.org:8080
req.URL.Host是空的
对于通过代理的请求,req.URL.Host是目标主机,req.Host是代理服务器。
对于不是走代理的请求,req.URL.Host是空的,req.Host是目标主机
一个利用go反向代理解决api转发的例子(go反向代理)的更多相关文章
- windows环境下 nginx+iis 反向代理解决跨域问题
项目基本完成,是时候花点时间整理一下最近的姿势了 1 什么是跨域? 网上对于跨域的概念会有大篇幅的文章去解释,似乎有点玄乎,初学者很容易对这个概念产生恐惧,跨域其实很简单,其实只要知道一点,无法跨域访 ...
- 利用nginx做反向代理解决前端跨域问题
最近朋友再群里提了一个问题,他们公司给他提供了一个获取数据的接口,在浏览器访问这个接口能获取到json数据,但是放在项目里使用ajax就产生了跨域问题,一般这个需要提供接口的后台方面需要做跨域处理,但 ...
- 前端通过Nginx反向代理解决跨域问题
在前面写的一篇文章SpringMVC 跨域,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式: JSONP CORS WebSocket 可是这几种方式都是基 ...
- nginx反向代理-解决前端跨域问题
1.定义 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源.注意:跨域限制访 ...
- nginx反向代理解决跨域问题
跨域:浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 下表格为前后端分离的域名,技术信息: 域名 服务器 使用技术 前端 http://b.yynf.com ...
- Nginx入门及如何反向代理解决生产环境跨域问题
1.Nginx入门与基本操作篇 注:由于服务器是windows系统,所以本文主要讲解Nginx在windows下的操作. 首先下载Nginx 解压缩,我们所有的配置基本都在万能的 nginx/conf ...
- Nginx 反向代理解决跨域问题分析
当你遇到跨域问题,不要立刻就选择复制去尝试.请详细看完这篇文章再处理 .我相信它能帮到你. 分析前准备: 前端网站地址:http://localhost:8080 服务端网址:http://local ...
- [转]用apache反向代理解决单外网ip对应内网多个web主机的问题
用apache反向代理解决单外网ip对应内网多个web主机的问题 转载一个有独立外网IP,需内网服务器对外发布的例子,是应用apache虚拟主机的. 来源地址:http://www.itshantou ...
- 使用 ssh -R 建立反向/远程TCP端口转发代理
转自:https://yq.aliyun.com/articles/8469 ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术.http://b ...
- 使用nginx反向代理解决前端跨域问题
1. 首先去Nginx官网下载一个最新版本的Nginx,下载地址:http://nginx.org/en/download.html.我这里下载的版本是:nginx/Windows-1.12.0.下载 ...
随机推荐
- 一文详解 Netty 组件
作者:京东物流 张弓言 一.背景 Netty 是一款优秀的高性能网络框架,内部通过 NIO 的方式来处理网络请求,在高负载下也能可靠和高效地处理 I/O 操作 作为较底层的网络通信框架,其被广泛应用在 ...
- 【0基础学爬虫】爬虫基础之自动化工具 Playwright 的使用
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶.逆向相关文章,为实现从易到难全方位覆盖,特设[0基础学爬 ...
- 将input 中的小写字母转化为大写字母
小写转换为大写,使用toLocaleUpperCase() options.element.find(".CarNumber").textbox({ label: '车牌号:', ...
- TienChin 渠道管理-前端展示渠道信息
在编写 Vue 项目的时候我们可以使用 IDEA 当中提供的一个工具叫做 structure,也就是说可以很轻松的列举出当前 Vue 文件的大致结构,点那个就会跳转到对应的地方. 简简单单介绍一个编写 ...
- OCR文字检测与识别系统:融合文字检测、文字识别和方向分类器的综合解决方案
1. OCR文字检测与识别系统:融合文字检测.文字识别和方向分类器的综合解决方案 前两章主要介绍了DBNet文字检测算法以及CRNN文字识别算法.然而对于我们实际场景中的一张图像,想要单独基于文字检测 ...
- vue-router.esm.js:2065 Uncaught (in promise) Error: Redirected when going from "/login?redirect=%2Fhome" to "/home" via a navigation guard.
原因: vue-router路由版本更新产生的问题,导致路由跳转失败抛出该错误; 真正的原因是由于返回了一个Promise对象, 正常的跳转由then方法执行 当正常的路由跳转, 被"路 ...
- 进程锁(互斥锁)(Python)
3:# 抢票示例 import json import time from multiprocessing import Process,Lock def search(i): with open(' ...
- 苹果新一代“超级芯片”曝光:M3 Ultra最高可达32核CPU
近日,据外媒消息,苹果计划在2024年推出新一代"超级芯片"M3 Ultra. 据悉,M3 Ultra将大幅增加CPU核心数量,同时GPU核心数量也将适度增加. 具体来说,M3 U ...
- Window Server+IIS配置实现一台服务器绑定多个HTTPS证书
参考原文链接:https://blog.csdn.net/lengyiqiu/article/details/89182239 此处做个记录防止丢失: 直接上步骤: 1.选安装好SSL证书,供下面配置 ...
- CF131D Subway 题解
题目传送门 前置知识 强连通分量 | 最短路 解法 考虑用 Tarjan 进行缩点,然后跑最短路. 缩点:本题的缩点有些特殊,基于有向图缩点修改而得,因为是无向图,所以在 Tarjan 过程中要额外记 ...