如何在 fetch API 得到 302 时将 `?token=...` 附加到重定向 URL?

How to append `?token=...` to the redirect URL when fetch API got 302?

如题。我对这个主题很陌生,所以我将使用这个例子来描述我想要实现的目标:

  1. 我正在浏览一个 Git 页的网站,其中有一些图片。当我点击这些图像时,我发现 URL 附加了 ?token=DSKLFJOS...
  2. 现在如果我只复制 URL 而没有这个标记,那么我将得到 404 作为响应。
  3. 我发现404其实是第二次请求。第一个请求是302,可以从响应中找到token。
  4. 所以,我想要实现的是,我想使用 fetch API 尝试从 302 获取令牌,并将其附加到 ( redirect) request ?token=... 这样第二个请求就会得到 200.

我的想法:也许在我对fetchAPI的credentialsand/orredirect选项了解更多之后可以实现。但我不确定!

这是当前代码,它将因 404(在第二次请求时)而失败。不是我写的,所以看不懂。 (抱歉,我无法 post 完整代码,因为它是私人内容)

    fetch(filePath)
      .then(response => response.arrayBuffer())
      .then(arrayBuffer => callback(arrayBuffer, arrayBuffer.byteLength));

感谢您的阅读。如果我的任何想法不正确,请随时纠正我并post作为答案!

您可以使用新的 URL 和 fetch(originalResponse.url + token) 提出另一个请求。

The url read-only property of the Response interface contains the URL of the response. The value of the url property will be the final URL obtained after any redirects.

来自 https://developer.mozilla.org/en-US/docs/Web/API/Response/url

这是一个例子:

let token = "abcdef"
fetch("page-that-redirects.com/")
  .then(response => {
    if (response.status === 404) {
      fetch(response.url + "?token=" + token)
        .then(/* do something */)
    }
  })

// Or with async/await:
let response = await fetch("page-that-redirects.com/")
if (response.status === 404) {
  let newResponse = await fetch(response.url + "?token=" + token)
  /* do something */
}


也许这样的事情会奏效。基本上,您只需检查状态代码,如果它是 302,您将 re-fetch 带有令牌的响应,然后如果状态仍然大于 300,您 return null,如果不是,您 return JSON 响应。

async function getImage(url, token) {
  let response = await fetch(url);
  
  // You can also say if (response.status >= 300 && response.status < 400)
  if (response.status === 302) {
    response = await fetch(`${url}?token=${token}`);
  }
  
  if (response.status >= 300) {
    return null;
  }
  
  return response.json();
}

headers 位置应该是这样的:

async function getImage(url) {
  let response = await fetch(url);
  
  if (response.status === 302) {
    response = await fetch(`${url}?token=${response.headers.get('location')}`);
  }
  
  return response.json();
}

如果只是为了简化答案并考虑到请求会成功,我删除了第二个。