2013-03-27 3 views
24

Ich habe einen API-Dienst mit NancyFX gemacht, und ein paar Front-End-Entwickler erstellen einen SPA JS-Client gegen diese API.Ist es möglich, CORS mit NancyFX zu aktivieren?

Wir möchten den clientseitigen Code gegen den veröffentlichten Server testen, ohne den Clientcode mit zu viel Häufigkeit veröffentlichen zu müssen.

Aber der Client läuft auf localhost, und der Server ist in Windows Azure.

Ist es möglich und einfach, CORS auf dem NancyFX Server zu aktivieren? Wie kann ich das machen?

Danke.

Antwort

31

Es ist möglich, dies in der bootstraper von Nancy

protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) 
    { 

     //CORS Enable 
     pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) => 
     { 
      ctx.Response.WithHeader("Access-Control-Allow-Origin", "*") 
          .WithHeader("Access-Control-Allow-Methods", "POST,GET") 
          .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"); 

     }); 
+1

dies funktionierte für mich, aber nicht für den Post, :( –

+1

Das ist wirklich seltsam. In dieser Zeile 'WithHeader (" Access-Control-Allow-Methoden "," POST, GET ")' Sie erlauben die Methoden, die Sie brauchen. – oaamados

27

Wenn Sie IIS als Host für Nancy verwenden, in diesem Fall für Windows Azure, können Sie einfach die Datei web.config aktualisieren, um die Kopfzeile jeder Anfrage hinzuzufügen.

Dies kann durch Hinzufügen des folgenden geschehen: Sie tun können,

<system.webServer> 
    <httpProtocol> 
    <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
    </customHeaders> 
    </httpProtocol> 
</system.webServer> 

Alternativ was Sunny vorgeschlagen, und wenn Sie jedes Mal das Schreiben nicht mögen, dass Sie Ihre eigene Erweiterungsmethode hinzufügen:

public static class NancyExtensions 
{ 
    public static void EnableCors(this NancyModule module) 
    { 
     module.After.AddItemToEndOfPipeline(x => 
     { 
      x.Response.WithHeader("Access-Control-Allow-Origin", "*"); 
     }); 
    } 
} 

Dann können Sie einfach this.EnableCors() in Ihrer Route anrufen.

+0

Gibt es eine Möglichkeit, dies zu sichern? Ich meine, sicher sein, dass nur ein bestimmter Kunde auf den gegebenen Endpunkt zugreifen kann? –

+0

@NorbertNorbertson Wenn Sie die API konsumieren, nehmen Sie die Anfrage an, validieren Sie sie, geben Sie die Kopfzeilen nur zurück, wenn der Benutzer gültig ist. – Phill

+0

Ich habe ein HTML-Formular, das an einen Nancy-Endpunkt sendet. Es funktioniert, aber ist es möglich, nur einer bestimmten Domain das Senden an diesen Endpunkt zu erlauben? –

11

zu tun, wenn Ihre HTTP-Anforderung ist simplePhill's answer wird dann ausreichen, aber wenn die Anforderung nicht so einfach ist, wird der Browser eine Vorkontrolle senden. Die Preflight-Prüfung ist eine OPTIONS-HTTP-Anfrage und dies muss ebenfalls behandelt werden. Hier

ist eine Erweiterung Methode CORS zu konfigurieren:

public static class MyNancyExtension 
{ 
    public static void EnableCORS(this Nancy.Bootstrapper.IPipelines pipelines) 
    { 
     pipelines.AfterRequest.AddItemToEndOfPipeline(ctx => 
     { 
      if (ctx.Request.Headers.Keys.Contains("Origin")) 
      { 
       var origins = "" + string.Join(" ", ctx.Request.Headers["Origin"]); 
       ctx.Response.Headers["Access-Control-Allow-Origin"] = origins; 

       if (ctx.Request.Method == "OPTIONS") 
       { 
        // handle CORS preflight request 

        ctx.Response.Headers["Access-Control-Allow-Methods"] = 
         "GET, POST, PUT, DELETE, OPTIONS"; 

        if (ctx.Request.Headers.Keys.Contains("Access-Control-Request-Headers")) 
        { 
         var allowedHeaders = "" + string.Join(
          ", ", ctx.Request.Headers["Access-Control-Request-Headers"]); 
         ctx.Response.Headers["Access-Control-Allow-Headers"] = allowedHeaders; 
        } 
       } 
      } 
     }); 
    } 
} 

Damit CORS nennen diese Erweiterungsmethode in der Bootstrap-Programm:

protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines) 
{ 
    base.ApplicationStartup(container, pipelines); 

    pipelines.EnableCORS(); 
} 

Bitte beachten Sie, es nicht NancyModule erweitert, weil OPTIONS is handled outside of module (auch here).