「把这个页面的地址发我」——听起来最简单的一件事,实际在不同场景里有不同的拿法。普通用户、开发者、爬虫、服务器端各有各的办法,拿错了就会拿到带一堆临时参数或者内网地址的链接。

普通用户:复制地址栏就够了

浏览器地址栏里那一串就是完整 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,后端防反代,爬虫看最终响应地址。