Avatar billede Mikker Praktikant
13. juni 2013 - 14:35 Der er 8 kommentarer og
1 løsning

ServiceStack GlobalResponseheaders virker ikke

Hej Eksperter

Jeg har lavet en meget simpel ServiceStack REST service som jeg kalder via JQuery.Ajax(). Jeg har lagt servicen op på et webhotel og tester så via JQuery fra min localhost (Altså er vi ude i et Cross domain scenarie).

For at tillade dette Cross domain kald tilføjer jeg flg. til min AppHost.Configure:

SetConfig(new EndpointHostConfig
{
  GlobalResponseHeaders = {
    { "Access-Control-Allow-Origin", "*" },
    { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
    { "Access-Control-Allow-Headers", "Content-Type" }   
  },                   
  DefaultContentType = "application/json"
});

Når jeg kalder servicen via JQuery.Ajax() med denne configuration sender JQuery en OPTIONS request og stopper så med flg. fejl:

OPTIONS ... Origin http://localhost:9665 is not allowed by Access-Control-Allow-Origin. jquery-2.0.2.min.js:6
XMLHttpRequest cannot load ... Origin http://localhost:9665 is not allowed by Access-Control-Allow-Origin.

Men hvis jeg istedet for indsætter flg. i web.config, så virker det fint:

<httpProtocol>
  <customHeaders>
    <clear />
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

I dette tilfælde sender JQuery først en OPTIONS request og derefter en GET request og jeg får mit ønskede resultat.

Så mit spørgsmål er hvorfor det går galt når jeg benytter GlobalResponseHeaders men fint når jeg bruger web.config?
Avatar billede janus_007 Nybegynder
13. juni 2013 - 19:44 #1
Er du sikker på at SetConfig bliver eksekveret? Sæt et break point ind :)

Hvad siger response header når du kigger med Fiddler eller lign.?
Avatar billede Mikker Praktikant
14. juni 2013 - 09:00 #2
Hvis jeg kalder servicen direkte fra Chrome (http://bevidsthed.net/employees) så kan jeg se i Fiddler at jeg i Responsen får:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type

Dette skyldes at requesten er en GET:
GET http://bevidsthed.net/employees HTTP/1.1

Når jeg kalder servicen via JQuery.Ajax(), så sendes der en preflight OPTIONS request først:
OPTIONS http://bevidsthed.net/employees HTTP/1.1

Og Responsen til denne OPTIONS request indeholder ikke Access-Control headerne, med mindre jeg tilføjet disse til Web.config istedet for set-config.
Avatar billede janus_007 Nybegynder
15. juni 2013 - 14:37 #3
mythz skiver lidt om det her:
http://stackoverflow.com/questions/13741397/servicestack-cors-feature


Men må jeg spørge hvorfor du bruger OPTIONS?
Avatar billede Mikker Praktikant
15. juni 2013 - 19:30 #4
Hej Janus

Tak for linket. Det kigger jeg lige på...

Jeg vælger ikke selv OPTIONS. Browseren/JQuery sender først en OPTIONS request når der er tale om et Cross Domain kald. Browseren bruger OPTIONS-kaldet til at afgøre (vha. Response headeren fra serveren) om udvikleren af servicen har givet tilladelse til et Cross Domain kald til servicen. Dette angiver udviklere ved at tilføje de tre Response headere (Access-Control-Allow-...).

//mich@el
Avatar billede Mikker Praktikant
15. juni 2013 - 19:42 #5
Hej Janus

Jeg har nu kigget på Mythz's indlæg, men det siger mig ærlig talt ikke ret meget.

//mich@el
Avatar billede janus_007 Nybegynder
17. juni 2013 - 21:09 #6
Jeg ville nok bare smide dette ind i Config funktionen som SS kalder:

Plugins.Add(new CorsFeature()); //Registers global CORS Headers

this.RequestFilters.Add((httpReq, httpRes, requestDto) => {
  //Handles Request and closes Responses after emitting global HTTP Headers
    if (httpReq.Method == "OPTIONS")
        httpRes.EndServiceStackRequest();
})
Avatar billede Mikker Praktikant
18. juni 2013 - 14:24 #7
Hej Janus

Tak for dit besyv, men det ser desværre ikke ud til at gøre nogen forskel. Min ServiceHost-fil ser nu således ud:

using ServiceStack.ServiceInterface.Cors;
using ServiceStack.WebHost.Endpoints;
using ServiceStack.WebHost.Endpoints.Extensions;

namespace ServiceStackTest
{
    public class EmployeeServiceHost : AppHostBase
    {
        public EmployeeServiceHost() : base("EmployeeService", typeof(EmployeeService).Assembly) { }
        public override void Configure(Funq.Container container)
        {
            Plugins.Add(new CorsFeature()); //Registers global CORS Headers

            RequestFilters.Add((httpReq, httpRes, requestDto) =>
            {
                //Handles Request and closes Responses after emitting global HTTP Headers   
                if (httpReq.HttpMethod == "OPTIONS")
                    httpRes.EndServiceStackRequest();
            });

            Routes
                .Add<Employee>("/employees")
                .Add<Employee>("/employees/{id}");

            SetConfig(new EndpointHostConfig
                {
                    GlobalResponseHeaders = {
                        { "Access-Control-Allow-Origin", "*" },
                        { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
                        { "Access-Control-Allow-Headers", "Content-Type" }                       
                    },
                    DefaultContentType = "application/json"
                });

           
        }
    }
}

Men stadig, når jeg forsøger at hente data vha JQuery.Ajax(), så får jeg flg. response:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Date: Tue, 18 Jun 2013 12:19:00 GMT
Content-Length: 0

Og så sker der ikke videre.

Den request som Ajax sender, ser således ud:

OPTIONS http://bevidsthed.net/employees HTTP/1.1
Host: bevidsthed.net
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: http://localhost:9665
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Access-Control-Request-Headers: accept, origin, content-type
Accept: */*
Referer: http://localhost:9665/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,da;q=0.6,de;q=0.4,sv;q=0.2,no;q=0.2
Avatar billede janus_007 Nybegynder
19. juni 2013 - 22:20 #8
Tjaa.. kan ikke komme på noget andet :|
Avatar billede Mikker Praktikant
12. august 2013 - 08:12 #9
Lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester