【问题标题】:ServiceStack CORS request failing even though OPTIONS preflight checks out即使 OPTIONS 预检签出,ServiceStack CORS 请求也会失败
【发布时间】:2014-07-26 20:09:39
【问题描述】:

我已在 ServiceStack 中为所有动词、标准标题加上一些自定义标题和所有来源启用了 CORS 功能。从我的 Angular 应用程序中,我在尝试对服务器进行 PUT 调用时收到 CORS“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误。如果我查看我的流量,我会看到对资源的​​ OPTIONS 预检请求返回一个有效的 200 消息,并且 ACAO 标头存在并设置为 *。

// CORS PREFLIGHT REQUEST
OPTIONS /referral HTTP/1.1
Host: api.mydomain.com
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://127.0.0.1:9000
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
Access-Control-Request-Headers: accept, x-uatoken, x-ualocation, content-type
Accept: */*
Referer: http://127.0.0.1:9000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

// CORS RESPONSE
HTTP/1.1 200 OK
Cache-Control: private
Vary: Accept
Server: Microsoft-IIS/8.0
X-Powered-By: ServiceStack/4.020 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-UAToken, X-UAUser, X-UALocation, Authorization
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 05 Jun 2014 17:27:47 GMT
Content-Length: 0

注意:我正在使用 angular-file-upload 库将此请求作为 multipart/form-data(从 Request.Files 中提取文件并从服务器上的 Request.FormData 中反序列化数据)。在 Chrome 中调试第二个请求(实际的 PUT)会显示有关“显示临时标头”的消息,因此我不确定该数据有多大用处:

Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----WebKitFormBoundary3rvpR6k8pz4rghGy
Origin:http://127.0.0.1:9000
Referer:http://127.0.0.1:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
X-UALocation:7
X-UAToken:yoqoByj-T1SBDHCYir92JQ
Request Payload
...etc...

有什么想法吗?

【问题讨论】:

  • 除了 Chrome 之外的其他浏览器是否也可以使用?见stackoverflow.com/a/21103081/215502
  • 从昨天开始,我一直在尝试自己解决同样的问题。唯一的区别是我使用的是 jQuery File Upload。起初我认为这可能是 localhost chrome CORS 问题。但是我已经在 IIS 和所有浏览器中安装了测试服务器和同样的问题。预检按预期进行,文件上传开始。然后,当它完成发布文件时,Chrome 会响应请求的资源上不存在“Access-Control-Allow-Origin”标头。即使我在 ServiceStack 中使用全局 CorsFeature 插件......所有请求都有那个标题!!!
  • 我还注意到另一件事,我可以对同一个端点执行一个简单的 $.ajax POST 并且它会成功。此外,如果我要通过 curl 进行文件上传,它会按预期进行,并且在响应标头中我会看到所有 Access-Control-Allow-* 标头。

标签: servicestack cors


【解决方案1】:

我看到预检检查正在请求 PUT 动词?您可能需要检查为 PUT/DELETE 动词设置 IIS(这是一大堆蠕虫)。或者只是尝试将请求作为 POST 来查看是否有效,然后您就知道它可能只是 IIS 中的动词。

【讨论】:

    【解决方案2】:

    我过去处理过这个问题,我不敢相信我直到现在才意识到它。它在您处理文件上传(如 PHP 或 Tomcat)的任何运行时环境中很常见。问题根本不是您的 CORS 设置(因为预检检查通过了)。除非它完全是别的东西,否则我猜你遇到了 ASP.NET 和 IIS 最大请求限制!默认情况下,这些都非常低(4MiB)。解决起来很简单,只需要在你的 web.config 中添加一些东西。 IIS 设置只有在您使用 IIS7.5+ 时才需要,我相信。还可能建议根据您允许上传运行多长时间(这将取决于客户端的速度和文件的大小)更改 executionTimeout。

    当我最终以调试模式运行 ServiceStack 项目并告诉它向我提出所有 .NET 异常时,我终于认识到了问题所在。尝试上传足够大的文件(我在 curl 中测试非常小的文件!doh!),然后异常清晰地击中了我。 System.Web.HttpException "超出最大请求长度。"

    这是您需要做的示例

      <system.web>
        <!-- maxRequestLength size is specified in kiB (int32). this controls max length handled by ASP.NET
             set to 2GiB currently
    
             executionTimeout is seconds before request is shutdown.
             set to 2 hours currently
             -->
        <httpRuntime targetFramework="4.5" maxRequestLength="2097152" executionTimeout="7200" />
      </system.web>
      <system.webServer>
        <security>
          <requestFiltering>
            <!-- size is specified in bytes (uint32). this controls max length of IIS
                 set to 2GiB currently -->
            <requestLimits maxAllowedContentLength="2147483648" />
          </requestFiltering>
        </security>
      </system.webServer>
    

    【讨论】:

    • 关于文件大小的有趣点,我已经对我的 web.config 进行了调整以防万一,但这不是我的问题。事实上,即使没有提交文件并且我只是以多部分形式发送 JSON,我也会遇到奇怪的 CORS 问题。
    • 该死的,我希望稍后为您节省有关文件大小问题的时间 :)。我看到预检检查正在请求 PUT 动词?您可能还想检查为 PUT/DELETE 动词设置 IIS(这是一大堆蠕虫)。我会尝试将请求作为 POST 来查看它是否有效,那么您知道它可能只是 IIS 中的动词。
    • 这是个好主意,因为 PUT 是“复杂的”,而 POST 是“简单的”。不知道为什么。我想在“PUT”=创建新项目和“POST”=更新现有项目的地方保持清洁,但我可能会尝试所有 POST 看看是否有帮助。如果有,我会在这里更新。谢谢!
    • 请添加您的建议,将 PUT 动词切换为 POST 作为答案,我会全部接受。日。长。我做出了改变,现在一切都变得超级棒了。我不敢相信。这些 CORS 错误使开发人员验证和故障排除成为 PITA,但仅此而已!谢谢你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-16
    • 2015-08-04
    • 2014-02-14
    • 2017-04-19
    • 1970-01-01
    • 2018-01-29
    • 2015-11-24
    相关资源
    最近更新 更多