你遇到的情况非常典型:其他系统(如静态网页、Java/Python应用)隐藏端口只需 Nginx 反向代理即可,但 WordPress 会“强制”显示端口,是因为 WordPress 自身逻辑在生成链接时,强行从数据库中读取了带端口的旧地址,或者错误判断了当前协议和主机名。 m A% X) }, |, i. }9 |
' [- ]; ~; w+ y4 U3 t) \简单来说,Nginx 把请求转发进去了,但 WordPress 返回给浏览器的 HTML 代码里,所有的 <a href>、<img src> 甚至重定向(301/302)地址里都写着 http://域名:端口。浏览器拿到这个地址后,自然就会显示出端口。- P: y' A9 L8 y" J( q5 i2 j
$ k: x% l5 f: }
要彻底解决 WordPress 的“强制显示端口”问题,必须在 WordPress 内部层面进行修正,而不仅仅是在服务器层面做代理。请按照以下三个步骤操作,缺一不可:* Y# n+ t8 ^' o
8 l/ Q( J/ n! z- \' i3 a& k
第一步:修改 wp-config.php(最核心步骤)3 F. Y0 r( w3 E* s) P) f
这是解决 WordPress “顽固”显示端口的最有效方法。通过定义常量,强制 WordPress 忽略数据库中的旧设置,动态使用当前访问的域名和协议。/ G* @/ f1 P1 C* {$ C% e) L9 a
% t ?, a& Y1 Y; m+ l% L4 W3 w7 {' M6 _请在你的 WordPress 根目录下的 wp-config.php 文件中,找到 /* That's all, stop editing! Happy publishing. */ 这一行,在它之前添加以下代码:
+ F( D% U5 d v# F
0 `6 C- |4 |( L) \- e9 g! vphp
O; W/ K' X; m/** 强制修正站点地址,解决内网穿透端口显示问题 */4 D; ]3 d8 V- i) M4 C
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
- P c, |1 s- l. f( Q $_SERVER['HTTPS'] = 'on';
- h1 u" @0 N/ z: F9 R}9 U* d7 T, P' L" d% I( B% ^* v
; \. J" y& d6 o: [+ B2 q// 动态获取当前访问的主机名(域名),自动隐藏端口1 m: `# M5 b" ?4 t, p* R0 p
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);$ j) D+ J* O' D4 g# v7 b) y
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
4 Y+ e Z. W5 j6 ~$ a9 L( Y
- p/ l# e9 c% s: `0 {// 如果你配置了 HTTPS,请将上面的 http 改为 https; l2 J3 U& W9 q: i2 ^/ Q+ o
// define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
+ }5 A- }0 T# v4 v1 k- `# X// define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);9 Z0 T6 X+ I$ u: W$ [* b
原理解释:" q9 R: i8 y, r- X3 _$ b# z4 m
# j: N" P4 {- y6 s. F4 z! ?
$_SERVER['HTTP_HOST'] 会获取用户浏览器实际访问的域名(例如 example.com),而不包含端口(因为浏览器访问标准80/443端口时不显示端口)。& @9 v/ k( [; k& ]3 Q( c" Z
通过 define 强制覆盖数据库中的 siteurl 和 home 值,WordPress 生成所有链接时都会使用这个动态获取的无端口域名。: z! s" ]6 R) z
第二步:清理数据库中残留的端口信息
% h+ q$ B; J" U: }/ \/ ?即使做了第一步,数据库中可能还残留着旧的带端口的 URL,导致某些插件或硬编码的链接依然显示端口。
: _6 ], l$ N% v5 W2 t3 F
" h* J8 }; \5 ^7 x/ D2 O) @5 a登录 phpMyAdmin 或使用命令行进入 MySQL。: P6 |$ e6 t% t8 Z
执行以下 SQL 语句,将数据库中所有带端口的旧地址替换为新的无端口地址(请根据实际情况修改域名):
6 V5 K# R# q0 _, i5 L$ b% Osql8 W+ m9 x8 Z7 J" a
-- 假设你的域名是 example.com,旧地址是 example.com:8080
' p1 }9 P( _3 Y/ d$ SUPDATE wp_options SET option_value = replace(option_value, 'http://example.com:8080', 'http://example.com') WHERE option_name = 'home' OR option_name = 'siteurl';# v* l4 w5 g: u
9 s7 U/ B0 t/ j
-- 替换文章内容和元数据中的链接
) p) Z% u+ V2 X0 c. }' ]! Z* d1 WUPDATE wp_posts SET post_content = replace(post_content, 'http://example.com:8080', 'http://example.com');7 E; i; r( l2 v7 d
UPDATE wp_postmeta SET meta_value = replace(meta_value, 'http://example.com:8080', 'http://example.com');
1 L( M/ {: _2 a% w" |9 a) b注意:如果你的表前缀不是 wp_,请修改为实际的前缀。5 |8 ~: ?2 E# o$ g; L1 r G$ i
+ D) @8 D. A1 j/ ~, Q0 e. ?第三步:检查 Nginx 反向代理配置(确保头信息正确传递)
1 x7 O$ f/ g* `- o. i6 m7 L$ D% c为了确保 WordPress 能正确识别协议(HTTP/HTTPS),Nginx 的配置必须包含 X-Forwarded-Proto 头。
3 d, {' j7 i( J5 J" Y8 X6 e4 w
: `; s% z; J' a/ E你的 Nginx 配置应该类似这样:: \+ F, y1 k. |0 ?, C# E; l# ?- _
% m- W# {7 g* pnginx6 P- h: K# I, V8 x) X0 M* E
server {
) `6 k5 G/ o3 l; W listen 80;' [ i) ]7 [5 s& B8 z
server_name your-domain.com; # 你的域名1 e- \ s7 c% J e' c
7 z! C$ F2 O0 V7 @0 W) _2 ]
location / {) G% z" F! J) G/ K2 Y
# 指向 frp 监听的 vhostHTTPPort 或本地 WordPress 端口
, ]6 P' a3 B2 _8 _6 q6 X- N! E proxy_pass http://127.0.0.1:7788; 1 k; Y# I, O/ `* E# {% t" l( i
, E: c$ w. O2 @; T
# 关键头信息,必须包含+ V3 D6 `: c" {- y( ?6 c; ~9 M
proxy_set_header Host $host;
) X1 A" A* g! ^" @ proxy_set_header X-Real-IP $remote_addr;
* m8 E( q$ t8 w) R; c proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
$ J- Y Z( Y2 o3 ^ proxy_set_header X-Forwarded-Proto $scheme; # 告诉 WordPress 原始请求是 http 还是 https
+ n2 `* ], j3 r8 b F; c/ @1 Q- w }
: @" D6 A/ T9 N. X}
" `% A& K+ g+ T$ L! D常见坑点排查
6 X. @" A2 ]2 {! r2 P. m缓存问题:修改完 wp-config.php 后,务必清除浏览器缓存、WordPress 缓存插件(如 WP Super Cache、W3 Total Cache)以及 CDN 缓存。否则你可能看到的还是旧的带端口的页面。, c, l! o' h% R9 u& b! ?
HTTPS 混合内容:如果你使用了 HTTPS,但 WordPress 内部仍生成 HTTP 链接,浏览器会报错或显示不安全。确保 wp-config.php 中的 WP_HOME 和 WP_SITEURL 使用 https://,并且 Nginx 配置了 SSL 证书。7 D; V. q6 B/ Q/ s( r- O# M8 P \
Frps 配置:确保 frps.ini 中的 vhostHTTPPort 和 vhostHTTPSPort 已设置,并且 Nginx 反向代理指向的是这些端口,而不是直接指向 WordPress 的本地端口(除非你直接在 frpc 中绑定了域名并使用了 vhost 模式)。1 k4 S! T. v( X) ]4 e V8 {5 V4 _* T1 X
总结:
" X; I$ [2 S; ~. U其他系统不显示端口是因为它们不存储“自我认知”的 URL,而 WordPress 存储了。通过 wp-config.php 中的 define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']); 这一行代码,你可以强制 WordPress “忘记”数据库中的带端口地址,从而彻底隐藏端口。
7 R/ @2 Z8 ~4 L# L3 @0 P& {$ n+ J8 k, D) ^' {
参考 |