【问题标题】:WebApi CORs - Access-Control-Allow-Origin header is present on request errorWebApi CORs - 请求错误时出现 Access-Control-Allow-Origin 标头
【发布时间】:2017-01-28 21:19:52
【问题描述】:

问题背景:

这似乎是一个常见的问题,我已经犯了一个错误。

我有一个当前托管在 Azure 中的标准 WebApi 和一个调用 AngularJS 应用程序,该应用程序调用所述 WebApi 上的端点。

调用 WebApi 的 AngularJS 应用 URL 是:

http://siteang.azurewebsites.net

而WebApi地址是:

https://site.azurewebsites.net

我想确保只有我在http://siteang.azurewebsites.net 的应用能够访问https://site.azurewebsites.net 的WebApi

问题:

我在将 AngularJS 应用程序提交到 WebApi 服务的表单中收到以下错误。

XMLHttpRequest cannot load https://site.azurewebsites.net/api/ShoppingComparison/GetC…itemIndex=Baby&itemtosearch=baby&lowToHigh=false&maxPrice=50000&minPrice=0.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://siteang.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 500.

守则:

以下是对 WebApi 服务的 $http 请求。

请注意,调用的 header 属性已设置为 AngularJS 站点的地址。

   loadSearchList: function (itemToSearch, itemIndex, countryCode) {
        self.itemToSearch = itemToSearch;
        self.itemCatagory = itemIndex;
        self.country = countryCode;

        self.searchList = [];

        $http({
            method: 'GET',
            url: 'https://site.azurewebsites.net/api/ShoppingComparison/GetComparisons',
            params: {
                itemtosearch: itemToSearch,
                itemIndex: itemIndex,
                countryCode: countryCode,
                maxPrice: '50000',
                minPrice: '0',
                highToLow: true,
                lowToHigh: false,
                amazonEbay: true,
                amazonOnly: false,
                ebayOnly: false
            },
            headers: {
                'Content-Type': 'text/plain; charset=UTF-8',
                'Access-Control-Allow-Origin': 'http://siteang.azurewebsites.net',
                'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE'
            }
        }).success(function (data) {

            //Success Handler.

        }).error(function (data) {

            //Error Handler.

        });

    }

以下是 AngularJS 应用程序正在调用的 WebApi 控制器。请注意,标头已设置为接受正在调用的http://siteang.azurewebsites.net 站点:

 [System.Web.Http.HttpGet]
    [EnableCors(origins: "http://siteang.azurewebsites.net", headers: "*", methods: "*")]
    public ViewItemModel GetComparisons([FromUri] ComparisonRequestModel comparisonModel)
    {
        return _callAndSearchApis.SearchApis(comparisonModel);
    }

任何帮助确定 WebApi 控制器拒绝此请求的原因将不胜感激。

【问题讨论】:

  • 它有认证吗?
  • 你测试了哪些浏览器?部分浏览器不支持CORS:caniuse.com/cors
  • 你打电话给config.EnableCors();了吗?
  • 您可以尝试的另一件事是删除headers: { 'Content-Type': 'text/plain; charset=UTF-8', 'Access-Control-Allow-Origin': 'http://siteang.azurewebsites.net', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE' },这样浏览器就不需要发送预检请求
  • @KhanhTO 感谢您的回复。我按照你说的做了并删除了 JSON 标头,这确实意味着我只能从一个特定的 Web 应用程序请求。但是,如果我将 WebApi URL 放入 POSTMAN 中,它仍然允许访问 API 并返回结果,这是为什么呢?

标签: c# angularjs asp.net-web-api


【解决方案1】:

很可能您的服务器返回了 500 错误,而 500 错误响应本身没有启用 CORS 标头。为了确认,我建议您使用Postman 之类的工具直接测试您的 API,并确保实际的 API 请求成功完成。

另外,您可以考虑是否希望各种服务器状态响应消息(对于 500、403、302 等)包含 CORS 标头。

【讨论】:

【解决方案2】:

首先,您在此处混合了 http 和 https 协议。检查您请求的网址是否有 https。请首先确保这是正确的。然后你需要弄清楚服务器是否拒绝以及它在做什么。启用 cors 的资源有很多。甚至 Stackoverflow 也有线程数。

https://stackoverflow.com/search?q=Enabling+Cors+WebApi

http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

编辑答案: 有时您的 IIS 会干扰预检 OPTIONS 请求。尝试在您的 web.config 中执行类似的操作,看看它是否有效。

http://benfoster.io/blog/aspnet-webapi-cors

【讨论】:

  • CORS 支持 HTTP-to-HTTPS 跨源请求。只有 IE8/9 使用的 XDomain 不支持它。
  • 我不是在谈论 http-to-https 请求,我没有注意到设置的标头,并且认为设置的允许来源与请求发送的标头之间存在差异。无论如何,这不是这里的问题。
  • 啊,我明白了。感谢您的澄清。
  • 谢谢你 :) ...它帮助我重新审视这个问题并意识到这不是问题。
【解决方案3】:

CORS 请求标头由浏览器自动强加用于跨源请求。没有办法改变它们。事实上,如果客户端可以设置 CORS 允许标头,CORS 将毫无意义。

您看到的错误是您的服务器在预检请求期间未在 响应 中包含所需的 Access-Control-Allow-* 标头。当客户端执行简单 GET 请求以外的操作时执行预检请求 (OPTIONS),包括添加自定义请求标头(您的 Allow 标头是)时。

说句公道话,错误(“...requested 资源上不存在”)可能不会帮助您解决困惑。

我建议从请求中删除 CORS 标头并重试。如果仍然失败,请使用 Fiddler 等 HTTP 代理捕获请求,并使用预检请求和响应中的 CORS 标头更新您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-07
    • 2021-12-02
    • 2017-04-15
    • 2023-03-03
    • 2021-12-19
    • 2018-09-19
    • 2019-06-19
    • 1970-01-01
    相关资源
    最近更新 更多