当我们客户端无法直接对服务器某些请求进行访问时,我们希望通过服务器中间代理进行访问并将结果返回给真正的客户端
1. 创建request请求
func Request(client *http.Client, url string) (*http.Response, error) {
// 创建HTTP请求
var resp *http.Response
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return resp, errors.New(fmt.Sprintf("创建http请求客户端失败: %v", err))
}
// 发送HTTP请求
resp, err = client.Do(req)
if err != nil {
return resp, errors.New(fmt.Sprintf("发送HTTP请求失败: %v", err))
}
return resp, nil
}
2. 页面代理访问
func NormalRequest(url string, c *gin.Context) {
// 创建HTTP客户端
client := &http.Client{}
response, err := s.Request(client, url)
defer response.Body.Close()
if err != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "查询失败"})
return
}
// 读取响应体
body, err1 := ioutil.ReadAll(response.Body)
if err1 != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "查询失败"})
return
}
// 返回html字符串页面
c.Header("Content-Type", "text/html")
c.Writer.Write(body)
}
3. 文件下载代理访问
func DownloadRequest(url, fileName string, c *gin.Context) {
// 创建HTTP客户端
client := &http.Client{}
response, err := s.Request(client, url)
defer response.Body.Close()
if err != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "查询失败"})
return
}
// 创建一个临时文件用于存储下载的文件
tmpFile, err1 := os.CreateTemp("", "download-*")
defer tmpFile.Close()
if err1 != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "创建临时文件失败"})
return
}
// 将响应体内容写入临时文件
_, err = io.Copy(tmpFile, response.Body)
if err != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "将响应体内容写入临时文件失败"})
return
}
// 将文件指针重置到文件开头
_, err = tmpFile.Seek(0, 0)
if err != nil {
c.JSON(status.StatusOK, gin.H{"code": status.StatusDatabaseFailed, "message": "将文件指针重置到文件开头失败"})
return
}
// 设置响应头,指示客户端这是一个文件下载
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName)) // fileName为指定文件名称
c.Header("Content-Type", "application/octet-stream")
// 将文件内容作为响应返回给客户端
c.Status(http.StatusOK)
c.File(tmpFile.Name())
// 可选:删除临时文件
os.Remove(tmpFile.Name())
}
当需要进行请求代理则可以选择不同的访问方式进行,文件下载则在需要判断代理访问之后返回的响应头部来调用DownloadRequest下载