简体   繁体   English

在Azure Web中启用CORS

[英]Enable CORS in Azure web

What I´m trying to do is to enable CORS (Cross-origin Resource Sharing) for .net MVC 5 Azure website when calling a https service (not my own) from my JavaScript . 我要做的是, 当从JavaScript调用https服务(不是我自己的)时,为.net MVC 5 Azure网站启用CORS(跨域资源共享)。

I always get the same error 我总是得到同样的错误

XMLHttpRequest cannot load https://someservice-I-have-no-control-over . XMLHttpRequest无法加载https:// someservice-I-have-no-control-over No 'Access-Control-Allow-Origin' header is present on the requested resource. 所请求的资源上没有“ Access-Control-Allow-Origin”标头。 Origin ' https://my.azurewebsites.net ' is therefore not allowed access. 因此,不允许访问源“ https://my.azurewebsites.net ”。 The response had HTTP status code 400. 响应的HTTP状态码为400。

I have managed to enable this when developing locally, setting my project to https and adding the following to web.config 在本地开发,将项目设置为https并将以下内容添加到web.config时,我设法启用了此功能

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS"/>
    <add name="Access-Control-Allow-Headers" value="Content-Type, Accept, SOAPAction"/>
    <add name="Access-Control-Max-Age" value="1728000"/>
  </customHeaders>
</httpProtocol>
</system.webServer>

That adds the ' Access-Control-Allow-Origin ' header. 这添加了“ Access-Control-Allow-Origin ”标题。 But that does not seem to work on the Azure website. 但这在Azure网站上似乎不起作用。

And I can´t find any settings like in the Mobile Services where you can allow this like you see here. 而且我找不到像“移动服务”中那样的任何设置,您可以在其中允许此设置,如此处所示。

移动服务的CORS

Since I know you are all going to ask for code (that works locally btw) there you have the simple Jquery call to the service 因为我知道你们都会要求代码(在本地工作),所以您可以对服务进行简单的Jquery调用

$.ajax({
    url: 'https://someservice-I-have-no-control-over',
    dataType: 'json',
    contentType: 'application/json',
    type: 'GET',
    success: function (response) {
        $.each(response, function (key, value) {
          console.log("success"); //Doesn´t happen! :-(
        });
    },
    error: function (xhr, text, error) {
        if ($.isFunction(onError)) {
            onError(xhr.responseJSON);
        }
    }
});

So any thoughts? 有什么想法吗?

Edit 1 编辑1

Just to clarify a little. 只是澄清一下。

I am calling a service that I have no control over that is a https one, in a javascript (not a controller) that is mine. 我在我的JavaScript(不是控制器)中调用了我无法控制的服务,即https。

Edit 2 编辑2

Ok I thought that I could intercept the response from the third party service and add this header before the browser rejects it. 好的,我认为我可以拦截来自第三方服务的响应,并在浏览器拒绝它之前添加此标头。 As I see it that is not possible (right?). 我认为这是不可能的(对吗?)。 But how come it works locally ? 但是它在本地如何运作

If I capture the call to this service with eg LiveHTTPHeaders I get the following response where there is not a "Access-Control-Allow-Origin" restriction (so way does it work locally?). 如果我使用LiveHTTPHeaders等捕获对该服务的调用, 则会收到以下响应,其中没有“ Access-Control-Allow-Origin”限制(这样它在本地可以工作吗?)。

Request (to https://someservice-I-have-no-control-over.com ) 请求(至https://someservice-I-have-no-control-over.com

GET /someservice-I-have-no-control-over/SomeAction/44 HTTP/1.1
Host: someservice-I-have-no-control-over.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
If-None-Match: "53867cff-96b0-411f-88b7-d84765f9f8e8"
Cache-Control: max-age=0

Reply 回复

HTTP/1.1 304 Not Modified
Cache-Control: max-age=900
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Date: Tue, 24 Feb 2015 11:06:53 GMT

Not possible. 不可能。

It works locally because it's the server that must have the allow headers, and when you call your own webserver from your javascript you can add those headers. 它在本地工作,因为服务器必须具有allow标头,并且当您从JavaScript调用自己的网络服务器时,可以添加这些标头。

When you call the real website they do probably not add the CORS allow header ( Access-Control-Allow-Origin ) and your request is therefore denied. 当您致电真实网站时,他们可能未添加CORS允许标头( Access-Control-Allow-Origin ),因此您的请求被拒绝。

What you could do is either to use JSONP or proxy all requests through your own website. 您可以使用JSONP或通过自己的网站代理所有请求。

You could for instance use my CORS proxy: https://github.com/jgauffin/corsproxy . 例如,您可以使用我的CORS代理: https : //github.com/jgauffin/corsproxy It's intended usage is for IE9 and below, but works just as fine for all requests. 它打算用于IE9及以下版本,但对于所有请求都一样有效。

WebApiConfig I set it the WebApiConfig class and it worked. WebApiConfig我将其设置为WebApiConfig类,并且可以正常工作。 I also had issues on Azurewebsites when trying to set it via web.config. 尝试通过web.config进行设置时,我在Azure网站上也遇到了问题。

Try this in WebApiConfig: 在WebApiConfig中尝试以下操作:

   var cors = new EnableCorsAttribute("*", "*", "*");

   config.EnableCors(cors);

You can edit the " ", " ", "*" if you don't want to allow everything. 如果您不想允许所有内容,则可以编辑“ ”,“ ”,“ *”。

If you're using Owin, you can do this in the Startup.cs file: 如果您使用的是Owin,则可以在Startup.cs文件中执行以下操作:

app.UseCors(CorsOptions.AllowAll);

Use this if and only if you intentionally plan to expose your API to all origins and headers. 仅当您有意计划将API公开给所有来源和标头时,才使用此选项。

Else, you can try it this way by decorating your controller or specific methods: 另外,您可以通过装饰控制器或特定方法来尝试这种方式:

 [EnableCors(origins: "http://someCallingService", headers: "*", methods: "*")]

Check out THIS article 看看这篇文章

I addressed this by installing the following package: 我通过安装以下软件包解决了这个问题:

Microsoft.AspNet.WebApi.Cors

...then using the Config.EnableCors() as described above and altering my web.config transform: ...然后使用如上所述的Config.EnableCors()并更改我的web.config转换:

In WebApiConfig.cs: 在WebApiConfig.cs中:

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();

        // Continue configuration as you wish... 
    }

Then, in the web.config transform, in my case named web.PPE.config because it's for Pre-Production: 然后,在web.config转换中,在我的情况下,命名为web.PPE.config,因为它用于生产前生产:

<system.webServer>
    <httpProtocol>
        <!-- custom headers necessary for CORS -->
        <customHeaders xdt:Transform="Replace">
        <clear /> <!-- the clear here is important! -->
        <add name="Access-Control-Allow-Origin" value="http://url-that-is-allowed-to-communicate-with-this-server.com" />
        <!-- must match server DNS address or SignalR can't communicate with Hub remotely -->
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

YMMV on whether to include the Allow-Credentials option. YMMV上是否包含Allow-Credentials选项。 I found that necessary with my need, which was to enable access to a SignalR hub on a remote Azure webserver/app instance. 我发现有必要满足我的需要,那就是允许访问远程Azure Web服务器/应用程序实例上的SignalR集线器。

Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM