Nuxt 获取URL API 之useRequestURL注意事项

461次阅读
没有评论

先看看useRequestURL的实现代码:

nuxt/packages/nuxt/src/app/composables/url.ts at main · nuxt/nuxt (github.com)

export function useRequestURL (opts?: Parameters<typeof getRequestURL>[1]) {
  if (import.meta.server) {
    return getRequestURL(useRequestEvent()!, opts)
  }
  return new URL(window.location.href)
}

https://github.com/unjs/h3/blob/58e33ff00b1db1cf86a780bf8b152c3f7e573350/src/utils/request.ts#L333C1-L344C2

export function getRequestURL(
  event: H3Event,
  opts: { xForwardedHost?: boolean; xForwardedProto?: boolean } = {},
) {
  const host = getRequestHost(event, opts);
  const protocol = getRequestProtocol(event);
  const path = (event.node.req.originalUrl || event.path).replace(
    /^[/\\]+/g,
    "/",
  );
  return new URL(path, `${protocol}://${host}`);
}

https://github.com/unjs/h3/blob/58e33ff00b1db1cf86a780bf8b152c3f7e573350/src/utils/request.ts#L275C1-L286C2

export function getRequestHost(
  event: H3Event,
  opts: { xForwardedHost?: boolean } = {},
) {
  if (opts.xForwardedHost) {
    const xForwardedHost = event.node.req.headers["x-forwarded-host"] as string;
    if (xForwardedHost) {
      return xForwardedHost;
    }
  }
  return event.node.req.headers.host || "localhost";
}

通过上面的代码逻辑可以看出,如果是客户端渲染,那么就是直接使用的是浏览器的API

new URL(window.location.href)

在服务端,复杂一点,虽然最后都是通过URL这个类来实例化一个url,但是实例化的参数可能会有变化。如果你的Nginx服务器反代时设置了Host,并且设置了Port

location / {
        proxy_pass http://127.0.0.1:3224;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;
        add_header X-Cache $upstream_cache_status;
        proxy_set_header X-Host $host:$server_port;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 30s;
        proxy_read_timeout 86400s;
        proxy_send_timeout 30s;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

比方是$server_port = 443,通过https://www.example.com访问,那么服务端拿useRequestURL().host就可能是www.example.com:443,客户端拿useRequestURL().host可能是www.example.com,导致不一致,虽然最后发生水合作用,还是会走new URL(window.location.href)

举个例子,设置网页的标题:

useHead({
  title: useRequestURL().host
})

审查元素看到可能是<title>www.example.com</title>,但是查看网络请求响应的网页内容<title>www.example.com:443</title>,就不一致了。

正文完
 0
wujingquan
版权声明:本站原创文章,由 wujingquan 于2024-06-12发表,共计2030字。
转载说明:Unless otherwise specified, all articles are published by cc-4.0 protocol. Please indicate the source of reprint.
评论(没有评论)