Safari中的跨源资源共享策略拒绝跨域重定向

Noo*_*les 8 safari cors

我们有一个api端点,可以重定向到另一台服务器.它通过XHR调用,似乎在大多数浏览器中都能正常工作,除了Safari(特别是在iOS上).

我在控制台中遇到的错误是:跨源重定向被跨源资源共享策略拒绝

我们在执行重定向的页面上和其他服务器上有CORS.重定向页面设置:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: false
Run Code Online (Sandbox Code Playgroud)

另一台服务器有:

Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)

如何在CORS策略中允许重定向?

saa*_*aaj 10

W3C规范和其他权威来源Access-Control-Allow-Origin在使用时直接禁止使用通配符Access-Control-Allow-Credentials: true.

注意:字符串"*"不能用于支持凭据的资源.

https://www.w3.org/TR/cors/#resource-requests

重要说明:在响应凭证请求时,服务器必须指定域,并且不能使用通配符.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

如果凭据模式是"包含",则Access-Control-Allow-Origin不能*.

https://fetch.spec.whatwg.org/#cors-protocol-and-credentials

进一步的步骤

因为你的问题缺乏细节,让我们做一些定义:

  • domain-a是您的客户端代码的域
  • domain-b是您的make请求的端点的域
  • domain-c是请求最终重定向到的域

首先,我想,你想做一个解决方法.只要您告诉所有端点都在您的控制之下,那么您要么:

  • 直接请求从domain-adomain-c(如果重定向依赖于参数,甚至可以发出条件请求)
  • 在后端公开另一个端点,将请求包装到domain-b

如果它确实违反规范,向WebKit跟踪器报告错误也很重要.为了更容易重现案例,我制作了一个CherryPy应用程序,您可以将其附加到报告中.运行它的步骤:

  1. 将"127.0.0.1 domain-a domain-b domain-c"添加到您的 /etc/hosts
  2. 将以下代码放入 corsredirect.py
  3. 在终端中运行这些命令

     virtualenv -p python3 venv
     . venv/bin/activate
     pip install cherrypy
     python corsredirect.py
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将浏览器指向http:// domain -a:8080并按下按钮

这是应用程序.

#!/usr/bin/env python3
'''
Add localhost aliases in /etc/hosts for "domain-a", "domain-b", "domain-c".

The flow is: [domain-a] --CORS-GET--> [domain-b] --redirect--> [domain-c].
Open as http://domain-a:8080/
'''


import cherrypy


def cors():
  cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'

cherrypy.tools.cors = cherrypy._cptools.HandlerTool(cors)


class App:

  @cherrypy.expose
  def index(self):
    return '''<!DOCTYPE html>
      <html>
      <head>
      <meta content='text/html; charset=utf-8' http-equiv='content-type'>
      <title>CORS redirect test</title>
      </head>
      <body>
        <button>make request</button>
        <script type='text/javascript'>
          document.querySelector('button').onclick = function()
          {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'http://domain-b:8080/redirect', true);
            xhr.onload = function()
            {
              var text = xhr.responseText;
              console.log('success', text);
            };
            xhr.onerror = function()
            {
              console.error('failure');
            };
            xhr.send();
          };
        </script>
      </body>
      </html>
    '''

  @cherrypy.expose
  @cherrypy.config(**{'tools.cors.on': True})
  def redirect(self):
    raise cherrypy.HTTPRedirect('http://domain-c:8080/endpoint')

  @cherrypy.expose
  @cherrypy.config(**{'tools.cors.on': True})
  @cherrypy.tools.json_out()
  def endpoint(self):
    return {'answer': 42}


if __name__ == '__main__':
  config = {
    'global' : {
      'server.socket_host' : '127.0.0.1',
      'server.socket_port' : 8080,
      'server.thread_pool' : 8
    }
  }
  cherrypy.quickstart(App(), '/', config)
Run Code Online (Sandbox Code Playgroud)


小智 0

您需要设置“Access-Control-Allow-Methods”标头。

Access-Control-Allow-Methods: *
Run Code Online (Sandbox Code Playgroud)