【问题标题】:Make a synchronous redirectable CORS request in Chrome在 Chrome 中发出同步可重定向 CORS 请求
【发布时间】:2017-12-27 13:22:27
【问题描述】:

考虑三个域:A、B 和 C。域 A 上的一段 JavaScript 代码对域 B 进行标准 同步 XMLHttpRequest GET 调用,只有一个 Accept 标头,除了默认的。然后域 B 重定向到域 C。两个响应​​(B 和 C)都将 Access-Control-Allow-Origin 设置为 *。这在 Firefox 中运行良好,正如我所听说的,在 Internet Explorer 中也是如此。但是,Chrome 似乎不允许这样做。然而,异步代码在 Chrome 中也可以工作。

直接向域 C(以及具有相同属性的假设域 D)的同步和异步请求都可以工作。

实际上对 AFAICT 没有帮助的相关事情

我在上面解释了一些简单的事情,以使欺骗锤子使用者更容易阅读:

其他:

  • 请求需要预检,但由于其他原因而失败。
    我的请求是simple,所以它不应该触发 CORS 预检。方法:GET;标头:Accept没有指定Content-Type 编辑:对于简单的请求,Content-Type needs to be specified,似乎。我相应地修复了代码示例。
  • 代码无论如何都会触发 CORS 预检,因为 the Accept value is non-standard
    目前不适用于 Chrome。
  • Chrome 让使用同步变得更加困难。 XHRs,据记录在 here
    不,这只是限制了我不使用的另一个功能。
  • 我既不控制域 B 也不控制域 C
  • 需要从域 B 到 C 的重定向

要测试的代码

以下代码发出一系列请求,首先同步到域 B(重定向到 C),然后异步,然后直接同步到域 C 和异步到 C,并记录结果。请注意,日志可能不会按该顺序排列,因为这基本上是异步的重点。另请注意,在这种情况下,域 B 没有具有Access-Control-Allow-Origin: *,但我已经在域 B 上测试了此代码(本地主机,因此此处不可用)。

function request(url, callback) {
  var synchronous = typeof callback !== 'function'
  var xhr = new XMLHttpRequest()
  if (!synchronous) {
    xhr.onload = callback
  }
  xhr.open('GET', url, !synchronous)
  xhr.setRequestHeader('Accept', 'application/vnd.citationstyles.csl+json')
  xhr.setRequestHeader('Content-Type', 'text/plain')
  xhr.send(null)
  return xhr
}

var previewLength = 100

function handle(passed, message, data) {
  var item = document.createElement('li')
  item.innerText = message + (passed ? ' passed: ' : ' failed: ') + data
  var list = passed ? p : f
  list.appendChild(item)
}

var doi = '10.1093/BIOINFORMATICS/BTT178'
var domainB = 'doi.org'
var domainC = 'data.crossref.org'

var urlRedirect = '//' + domainB + '/' + doi
var urlDirect = '//' + domainC + '/' + doi

// sync domain B->C request
try {
  var response = request(urlRedirect)
  handle(true, 'sync domain B->C', response.responseText.slice(0, previewLength) + '...')
} catch (e) {
  handle(false, 'sync domain B->C', e)
}

// async domain B->C request
request(urlRedirect, function() {
  if (this.responseText[0] === '{') {
    handle(true, 'async domain B->C', this.responseText.slice(0, previewLength) + '...')
  } else {
    handle(false, 'async domain B->C')
  }
})

// sync domain C request
try {
  var response = request(urlDirect)
  handle(true, 'sync domain C', response.responseText.slice(0, previewLength) + '...')
} catch (e) {
  handle(false, 'sync domain C', e)
}

// async domain C request
request(urlDirect, function() {
  if (this.responseText[0] === '{') {
    handle(true, 'async domain C', this.responseText.slice(0, previewLength) + '...')
  } else {
    handle(false, 'async domain C')
  }
})
Passed:
<ul id=p></ul>Failed:
<ul id=f></ul>

我的问题

  • 是否有任何文档说明 Chrome 为何以及何时这样做?
  • 是否有解决方法(即同步重定向 CORS 请求)?我知道您无法阻止 XMLHttpRequest 中的重定向,但也许还有其他方法。

我正在运行 Chromium 57.0.2987.98 32 位。

【问题讨论】:

  • 我认为只是同步调用最近已被弃用并从 Chrome 中删除。

标签: javascript google-chrome xmlhttprequest cors synchronous


【解决方案1】:

似乎它从 Chrome 69 及更高版本开始按预期工作,不知道如何以及为什么。

【讨论】:

    猜你喜欢
    • 2014-12-27
    • 2017-02-14
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2022-08-23
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多