「把这个页面的地址发我」——听起来最简单的一件事,实际在不同场景里有不同的拿法。普通用户、开发者、爬虫、服务器端各有各的办法,拿错了就会拿到带一堆临时参数或者内网地址的链接。
普通用户:复制地址栏就够了
浏览器地址栏里那一串就是完整 URL。注意几件事:某些网站会自动补上 #hash 或者追踪参数,分享前把问号后面的 utm_source 之类删掉。
开发者:从 location 对象里取
location.href // 完整地址,含参数和 hash
location.origin // 协议 + 域名 + 端口
location.pathname // 路径部分
location.search // ? 开始的查询串
location.hash // # 后面的部分拼接地址时优先用 location.origin 加 pathname,别拿 href 去截字符串,端口和协议变化会让那套逻辑失效。
服务端:不同框架的取法
PHP 里组合 $_SERVER 的几项:
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http')
. '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];Node 的 Express 用 req.protocol + '://' + req.get('host') + req.originalUrl。Java 的 Servlet 用 request.getRequestURL() 加 getQueryString()。
反代之后的坑在于:服务器看到的是内网 IP 和 http 协议,直接拼会得到 http://10.0.0.5:8080/xxx 这种无用地址。要在 Nginx 里转发 X-Forwarded-Proto 和 X-Forwarded-Host,服务端信任这些头再取值。
爬虫:别用 request.url
用 Python 的 requests 时,response.url 才是最终地址,request.url 是起始地址,中间有重定向就会不一致。做分页抓取要拿最终地址做基址,否则相对链接会解析到错误的位置。
几个容易忽略的点
- 末尾斜杠:/a 和 /a/ 在很多框架里是两个不同的路由。
- 编码:中文路径在地址栏会显示成 %E4%B8%AD,复制出来后别手动改。
- 短链:分享出去的是短链,需要跟一次跳转才知道真实地址。
- 二维码:扫出来的是 URL,生成时别把内网地址编进去。
一句话:用户看地址栏,前端看 location,后端防反代,爬虫看最终响应地址。