你遇到的情况非常典型:其他系统(如静态网页、Java/Python应用)隐藏端口只需 Nginx 反向代理即可,但 WordPress 会“强制”显示端口,是因为 WordPress 自身逻辑在生成链接时,强行从数据库中读取了带端口的旧地址,或者错误判断了当前协议和主机名。; Q$ U; }- Y* l( l* o( O* O, F
# E) J9 {! F+ H) R3 l
简单来说,Nginx 把请求转发进去了,但 WordPress 返回给浏览器的 HTML 代码里,所有的 <a href>、<img src> 甚至重定向(301/302)地址里都写着 http://域名:端口。浏览器拿到这个地址后,自然就会显示出端口。
, `4 M. n; W: E1 ]% d/ d( r" n5 m* z% D0 d" h$ s3 k+ z0 f0 N' i
要彻底解决 WordPress 的“强制显示端口”问题,必须在 WordPress 内部层面进行修正,而不仅仅是在服务器层面做代理。请按照以下三个步骤操作,缺一不可:
- m2 e( h3 E# K/ `; }
: ^! f3 b6 A1 t! P' K7 s第一步:修改 wp-config.php(最核心步骤)
6 }6 H$ `* g O' T# E7 t这是解决 WordPress “顽固”显示端口的最有效方法。通过定义常量,强制 WordPress 忽略数据库中的旧设置,动态使用当前访问的域名和协议。4 B, K( E& Z; w
( a8 I' N$ G" U/ M# X- ~6 W
请在你的 WordPress 根目录下的 wp-config.php 文件中,找到 /* That's all, stop editing! Happy publishing. */ 这一行,在它之前添加以下代码:
, y9 o2 P6 r, l% r* V3 M
7 M* k+ t8 Y, l( v( R0 Ophp
( x- r- y8 ~9 n2 J7 n# f, E& \/** 强制修正站点地址,解决内网穿透端口显示问题 */
% e# P* R6 Q$ s/ r1 k, o. C- k4 fif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {, @: f: G$ s- n, r( c; ?
$_SERVER['HTTPS'] = 'on';
! M3 ?) T/ u& d8 a9 m1 f6 [}
# \+ z0 f- H+ X" [2 ^0 l3 U n- r$ N: d/ _0 U
// 动态获取当前访问的主机名(域名),自动隐藏端口; \* u* v, o9 v$ M/ L/ |
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);7 k2 `# m' f0 [1 m* S: R0 d+ {
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
- F9 Y4 Q' u$ A& J( r0 v& a* Z' _, s2 G/ }; O7 r
// 如果你配置了 HTTPS,请将上面的 http 改为 https0 ]; R/ e7 x, f* i4 e+ y
// define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
. _' m2 b' @9 B' B5 B# @// define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
2 }$ _" i6 Y/ t1 ^% y5 N' b. m原理解释:
+ z# U/ {4 |4 H. I3 ~- t7 d9 c( o' Q) ^! f
$_SERVER['HTTP_HOST'] 会获取用户浏览器实际访问的域名(例如 example.com),而不包含端口(因为浏览器访问标准80/443端口时不显示端口)。
7 F# Z' Z$ T+ |; r+ V0 M6 [通过 define 强制覆盖数据库中的 siteurl 和 home 值,WordPress 生成所有链接时都会使用这个动态获取的无端口域名。
5 O- P1 [# }. K( N4 d k% e d8 E第二步:清理数据库中残留的端口信息" b: Y9 ]# D! \; K3 E7 C) @+ a$ F
即使做了第一步,数据库中可能还残留着旧的带端口的 URL,导致某些插件或硬编码的链接依然显示端口。0 I4 G& p5 j8 J' F" e
$ S7 [* | Z& O' c2 A; B: D登录 phpMyAdmin 或使用命令行进入 MySQL。
j* B! i# Q# L/ d B d2 S执行以下 SQL 语句,将数据库中所有带端口的旧地址替换为新的无端口地址(请根据实际情况修改域名):
- x9 u1 ~& @( Q8 S4 s0 t+ [* Bsql% F' W1 X' s+ m4 y! {- I
-- 假设你的域名是 example.com,旧地址是 example.com:80809 X6 q! F" N1 |' h. \- g2 X' X6 o. s
UPDATE wp_options SET option_value = replace(option_value, 'http://example.com:8080', 'http://example.com') WHERE option_name = 'home' OR option_name = 'siteurl';: f2 G' a' B) C" B+ F0 j
0 q4 g/ Z$ ]/ I. t" f) P* D-- 替换文章内容和元数据中的链接
" g: g$ f, |& M* D) n4 ]$ F7 P5 GUPDATE wp_posts SET post_content = replace(post_content, 'http://example.com:8080', 'http://example.com');
' K& F1 _# G' }# H2 V( _) B& BUPDATE wp_postmeta SET meta_value = replace(meta_value, 'http://example.com:8080', 'http://example.com');
. c0 c! |- D" |3 M注意:如果你的表前缀不是 wp_,请修改为实际的前缀。' M! g" o4 R9 u+ o# i* m
+ T# ^9 ^1 A) F2 A7 n/ _第三步:检查 Nginx 反向代理配置(确保头信息正确传递)
) a' Z0 Z7 I; A6 n# |1 ^( o为了确保 WordPress 能正确识别协议(HTTP/HTTPS),Nginx 的配置必须包含 X-Forwarded-Proto 头。' L* f' R# g R/ U; K
! g( H: [& q9 J5 J! f0 z: ^' y你的 Nginx 配置应该类似这样:
5 E3 Q e) o* |' m! }2 N) j# S% [7 q. _# C, U. x- a
nginx% Y- g' Z9 U. F7 q3 D
server {
4 Z( [3 n3 O- ?+ B: }! B listen 80;
4 h; |) W9 M& d: M$ a server_name your-domain.com; # 你的域名; x6 I7 m& B+ |9 n
( _% ^# }. L% w' D5 F v
location / {
2 w8 r0 z& C1 F8 G8 z5 o # 指向 frp 监听的 vhostHTTPPort 或本地 WordPress 端口
h/ j8 e& X7 k proxy_pass http://127.0.0.1:7788;
3 o9 }, C8 J' ~! H! R$ C6 O$ c & \7 @+ g- R1 Q& E* o/ k
# 关键头信息,必须包含
7 F6 a1 V( [5 B* Q" `, @& `# _ proxy_set_header Host $host;1 U/ r- J y. L4 W! g
proxy_set_header X-Real-IP $remote_addr;! j1 U3 Z" Q8 A, P1 p6 j6 L1 B; ?1 ?* L5 a
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;9 p0 `0 O- O- _/ i' V
proxy_set_header X-Forwarded-Proto $scheme; # 告诉 WordPress 原始请求是 http 还是 https
( K* w! l* N: }2 ^6 P0 l( ^: o" O }
- |, o0 ^3 C) v, |0 H+ w/ y}
7 {2 g4 X3 r8 {! {常见坑点排查, M; }- ]5 h* p! z
缓存问题:修改完 wp-config.php 后,务必清除浏览器缓存、WordPress 缓存插件(如 WP Super Cache、W3 Total Cache)以及 CDN 缓存。否则你可能看到的还是旧的带端口的页面。' k6 A3 P- B- [" g' j$ k2 x
HTTPS 混合内容:如果你使用了 HTTPS,但 WordPress 内部仍生成 HTTP 链接,浏览器会报错或显示不安全。确保 wp-config.php 中的 WP_HOME 和 WP_SITEURL 使用 https://,并且 Nginx 配置了 SSL 证书。
! w) s* D" J! i, p' f- sFrps 配置:确保 frps.ini 中的 vhostHTTPPort 和 vhostHTTPSPort 已设置,并且 Nginx 反向代理指向的是这些端口,而不是直接指向 WordPress 的本地端口(除非你直接在 frpc 中绑定了域名并使用了 vhost 模式)。
6 G$ i6 |& v6 q5 m$ n6 C总结:" Q( ?* y' F; K3 F" x3 R" ~' _
其他系统不显示端口是因为它们不存储“自我认知”的 URL,而 WordPress 存储了。通过 wp-config.php 中的 define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']); 这一行代码,你可以强制 WordPress “忘记”数据库中的带端口地址,从而彻底隐藏端口。5 r* J! U$ _! J; V8 @8 d
* z1 m' b$ ?* ?% L9 t参考 |