在Chrome

时间:2017-07-21 13:08:41

标签: javascript google-chrome xmlhttprequest cors synchronous

考虑三个域: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使用同步更加困难。 XHR,如记录here
    不,这只是限制我不使用的另一个功能。
  • 我不控制域B或C
  • 必须从域B重定向到C

要测试的代码

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

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位。

1 个答案:

答案 0 :(得分:0)

似乎可以从Chrome 69及更高版本开始正常运行,不确定如何以及为什么。