如何通过PHP将80端口流量转发至其他网站并返回响应
结论
你要实现的是标准反向代理逻辑,配置正确的前提下完全支持JS、HTML、CSS正常渲染,访问效果和直接打开目标站点没有差异。
这种模式下访客浏览器全程只和你的源站通信,地址栏不会跳转,后端由你的服务器代为向目标站拉取内容再回传给访客,只要规则覆盖完整,访客感知不到后端的转发动作。
实现方案
方案1:Nginx层代理(性能最好,优先选)
如果你有服务器Web服务配置权限,用Nginx直接做代理是效率最高的方案,不需要改PHP代码:
- 先匹配
/test.php路径,加上client0来源判断(可以按IP、自定义请求头、Cookie特征做识别) - 配置代理规则时把请求方法、请求头、请求体完整透传给目标站,拿到响应后再完整回传给访客
- 参考配置片段:
location /test.php { # 此处替换成你自己的client0判断规则,比如按IP匹配 if ($http_x_client_flag = "client0") { proxy_pass 填写你的目标站点完整地址; proxy_set_header Host 填写目标站点域名; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 透传Cookie,避免登录态丢失 proxy_cookie_domain 目标站点域名 你的源站域名; # 替换响应内的硬编码域名,解决静态资源路径错误 sub_filter 目标站点域名 你的源站域名/test.php; sub_filter_once off; } # 非client0的请求走原有test.php逻辑即可 }
注意:如果目标站的JS、CSS、图片、接口是放在其他路径下的,要把对应路径也加入代理规则,不然会出现资源404。
方案2:PHP代码层代理(适合无服务器配置权限的场景)
如果改不了Nginx配置,直接在test.php文件里写转发逻辑也能实现:
- 文件开头先判断当前请求是不是来自client0,不是就走原有业务逻辑
- 抓取当前请求的方法、头信息、请求体、参数,原样构造请求发给目标站对应路径
- 拿到目标站返回的响应后,把响应内容里硬编码的目标站域名替换成你自己的代理路径,再把响应头、响应体原样输出给访客
核心代码片段参考:
<?php // 替换成你自己的client0识别逻辑,示例按IP判断 $isClient0 = $_SERVER['REMOTE_ADDR'] == 'client0对应的IP'; if ($isClient0) { $targetPath = $_SERVER['REQUEST_URI']; $targetUrl = '你的目标站点完整地址' . $targetPath; $ch = curl_init($targetUrl); // 透传请求方法 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']); // 透传POST/PUT等请求的提交内容 $requestBody = file_get_contents('php://input'); curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); // 透传所有请求头 $requestHeaders = getallheaders(); curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); $response = curl_exec($ch); // 拆分响应头和响应内容 $headerLength = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $respHeaders = substr($response, 0, $headerLength); $respBody = substr($response, $headerLength); curl_close($ch); // 替换内容里的硬编码域名,避免资源加载失败 $respBody = str_replace('目标站点域名', '你的源站域名/test.php', $respBody); // 输出响应 foreach (explode("\r\n", $respHeaders) as $header) { header($header); } echo $respBody; exit; } // 原有test.php的业务逻辑写在这后面
避坑要点(直接影响页面能不能正常渲染)
- 规则要覆盖全路径:不能只代理
test.php单文件,页面引用的JS、CSS、图片、异步接口对应的路径都要纳入代理,不然会出现资源加载404,导致样式错乱、脚本跑不起来 - 硬编码路径必须替换:如果目标站的HTML、JS、CSS里写死了自身域名的绝对路径,一定要替换成你自己的代理路径,不然浏览器会直接请求目标站地址,出现跨域或者地址暴露的问题
- 头信息不要随便改:Cookie、Content-Type、编码相关的响应头要原样透传,不然会出现登录态失效、内容乱码、跨域拦截的问题
- 响应内容不要随意篡改:除了必要的域名替换,不要对JS/CSS/HTML内容做转码、压缩、注入操作,避免破坏原有代码的执行逻辑
内容的提问来源于stack exchange,提问作者p3ppi
相关产品推荐
相关产品推荐

