同事在群里说,把那个活动页地址发我。对方甩来一条带井号的链接,我打开停在页面顶部,活动区块根本没定位到。取 URL 这件事看着简单,场景选错就白忙一场。
地址栏那串字符拆成五段
拿 https://www.example.com:443/act/index.html?from=wx 举例,协议是 https,主机是 www.example.com,端口 443,路径是 /act/index.html,问号后面是查询串。末尾若还有井号加一段文字,那是片段标识,只在浏览器本地滚动用,不会发给服务器,所以服务端日志里永远看不到它。
浏览器里三种取法
- 地址栏:Ctrl 加 L 全选再复制,拿到的是当前真实地址,缺点是你滚动页面产生的井号片段也会被带上。
- 右键复制链接地址:只对超链接有效,取到的是 href 原值,站内常写成相对路径,粘到别处就打不开。
- 开发者工具:F12 切到 Network,刷新后右键第一条请求选 Copy as cURL,地址、请求头、Cookie 一次全拿到,调接口排错最省事。
前端脚本怎么取值
window.location.href 是完整地址,location.origin 只到协议加域名,location.pathname 是路径,location.search 带问号,location.hash 带井号。document.referrer 记录上一页,跨域或从书签进来时经常是空字符串。要把参数拼进新链接,中文和空格必须过一遍 encodeURIComponent,不然服务端解码出来是乱码。
服务端拿到的又是另一份
$_SERVER['REQUEST_URI']PHP 里这个变量给的是 /act/index.html?from=wx,只有路径和查询串,拼完整地址还要看 HTTP_HOST,以及 HTTPS 变量是否非空。Java 那边 request.getRequestURL() 返回协议、域名、路径,但不含参数,得再拼 getQueryString(),而且它返回的是 StringBuffer,直接当字符串用会少一截。
外发之前做两件事
- 删掉片段:井号后面的定位和一次性 token 都去掉,对方打开才不会报签名失效。
- 确认可达:192.168 开头的内网地址别人打不开,先确认链接不是本机 hosts 映射出来的测试域名。
判断标准很简单:要给别人用,就以浏览器地址栏为准再手动清理;要写进代码,就按运行时环境分别取,别把前端 location 那套搬到服务端。