0
votes

I'm developing an Azure MobileService / CordovaApp setup. The server runs locally and has the following setting to enable CORS:

<add name="Access-Control-Allow-Origin" value="*" />

The api can be called via browser using addresses like

http://localhost:59477/api/item/explore/A/B

The client script that's trying to depict this call is the following:

var client = new WindowsAzure.MobileServiceClient('http://localhost:59477/', 'http://localhost:59477/', '');
GetItems.addEventListener("click",
function ()
{
    client.invokeApi("item/explore/A/B",
        {
            method: "get"
        })
        .done(
        function (results)
        {
            alert(results.result.count);
        },
        function (error)
        {
            var xhr = error.request;
            alert('Error - status code: ' + xhr.status + '; body: ' + xhr.responseText);
            alert(error.message);
        }
    );
}
);

What I get is status 405 - Method not allowed, which I don't understand for two reasons:

  • The invoked Service Action is decorated with the [HttpGet] Attribute
  • The response headers seem to say GET is fine:
    HTTP/1.1 405 Method Not Allowed
    Allow: GET
    Content-Length: 76
    Content-Type: application/json; charset=utf-8
    Server: Microsoft-IIS/8.0
    X-SourceFiles: =?UTF-8?B?RjpcQ29kZVxGb290UHJpbnRzXGZvb3RwcmludHMuU2VydmVyXEZvb3RwcmludHNTZXJ2aWNlXGFwaVxmb290cHJpbnRcZXhwbG9yZVw1MS4yNzcwMjJcNy4wNDA3ODM=?=
    X-Powered-By: ASP.NET
    Access-Control-Allow-Origin: *
    Date: Sat, 15 Aug 2015 18:08:30 GMT

Any idea what I can do to get this running?


Edit The Raw request shows that, as already expected by Jeremy Foster, the client sends a request of the type OPTIONS:
OPTIONS http://localhost:59477/api/fp/get?id=1 HTTP/1.1
Host: localhost:59477
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:4400
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
Access-Control-Request-Headers: accept, x-zumo-features, x-zumo-installation-id, x-zumo-version
Accept: */*
Referer: http://localhost:4400/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

I managed to support this request applying the [HttpOptions] attribute to my action method. Now I get a more or less valid response:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B?RjpcQ29kZVxGb290UHJpbnRzXGZvb3RwcmludHMuU2VydmVyXEZvb3RwcmludHNTZXJ2aWNlXGFwaVxmcFxnZXRcMQ==?=
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Date: Sun, 23 Aug 2015 19:34:21 GMT
Content-Length: 234

         ...

At least that's what fiddler tells me. The AzureMobileServiceClient throws yet another issue, which roughly translates as:

Cross-Origin request blocked, missing token 'x-zumo-installation-id' in CORS header row 'Access-Control-Allow-Headers' on CORS-Preflight-Channel
2
I'm not sure it's wrong behavior for the client to issue an OPTIONS request. I'm guessing it's intended actually. It may be that an error response from an OPTIONS request is preferable to a failed GET request, so the client issues an OPTIONS first as a sort of "ping". Just a guess. Can't find anything in the documentation (which makes me suspect). I'm checking with some folks.Jeremy Foster

2 Answers

2
votes

Turn on Fiddler and try your api call from the browser and then again using the Mobile Services client and compare your raw HTTP requests to see what's different.

1
votes

Try to run through the CORS Support section of this blog post: http://azure.microsoft.com/blog/2014/07/28/azure-mobile-services-net-updates/.

A side note: The x-zumo-installation-id error you were getting was because the client requested access for a list of headers (see the Access-Control-Request-Headers in your request) and the server did not return that same list in the Access-Control-Allow-Headers header. Using the MS_CrossDomainOrigins setting as mentioned in the above blog post takes care of this by setting the allowed headers to * (all) by default.