2015-04-14 12 views
9

Ich habe eine ascx Seite GetToken.ashx.Header nicht für OPTIONS Ajax Anfrage

public void ProcessRequest (HttpContext context) { 
    context.Response.ContentType = "text/plain"; 
    context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 
    context.Response.Write(Token.CreateToken()); 
} 

Wenn ich AJAX auf dieser Seite, es gibt die folgenden Header:

Request Method:GET 
Status Code:200 OK 
Access-Control-Allow-Origin:* 
Cache-Control:private 
Content-Length:36 
Content-Type:text/plain; charset=utf-8 
Date:Tue, 14 Apr 2015 17:20:53 GMT 
Server:Microsoft-IIS/8.5 
X-AspNet-Version:4.0.30319 
X-Powered-By:ASP.NET 

Wenn die Seite, die die AJAX-Request macht in einer Sandbox iFrame gesetzt wird, zeigt es den Fehler:

XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 

und gibt den Header:

Request Method:OPTIONS 
Status Code:200 OK 
Allow:OPTIONS, TRACE, GET, HEAD, POST 
Content-Length:0 
Date:Tue, 14 Apr 2015 17:30:14 GMT 
Public:OPTIONS, TRACE, GET, HEAD, POST 
Server:Microsoft-IIS/8.5 
X-Powered-By:ASP.NET 

Ich kann nicht scheinen, um die OPTIONS Anfrage zum Hinzufügen der Kopfzeile zu erhalten. Das Hinzufügen von allow-same-origin zu den Sandbox-Eigenschaften ändert die Anfrage in eine GET, aber ich möchte dem iFrame diese Berechtigungen nicht erteilen.

Antwort

6

Ich gehe davon aus, dass Sie ashx zu schreiben bedeutete, nicht ascx. Das Vorhandensein der ProcessRequest (HttpContext context) Methode schlägt vor, dass es ein generischer Handler und kein Benutzersteuerelement ist.

Ich habe eine sehr einfache Seite gemacht haben mit testen:

<%@ Page Language="C#" AutoEventWireup="true" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
    <script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script> 
</head> 
<body> 
    <div id="testCorsDiv"> 
    </div> 
    <script type="text/javascript"> 
     $.ajax({ 
      type: "GET", 
      url: "/Handler/testCors.ashx", 
      dataType: "text", 
      success: function (theData) { $("#testCorsDiv").text(theData); }, 
      error: function (theData) { alert('error'); } 
     }); 
    </script> 
    <% if(string.IsNullOrEmpty(Request.QueryString["sandboxed"])) { %> 
    <iframe src="http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true" sandbox="allow-scripts" width="600"> 
    </iframe> 
    <% } %> 
</body> 
</html> 

lade ich die Seite auf http://localhost:49253/SandboxTest.aspx. Die Seite macht dann eine ajax Anfrage an http://localhost:49253/Handler/testCors.ashx und setzt die Ausgabe davon in die testCorsDiv div. Dies erzeugt eine direkte GET an den Handler (da es vom selben Ursprung kommt) und die Ausgabe wird eingefügt.

In der Seite ist auch eine Sandbox iframe, die die gleiche Seite lädt mit der URL http://127.0.0.1:49253/SandboxTest.aspx. Die ?sandboxed=true ist da, um zu verhindern, dass der Iframe einen inneren Iframe rekursiv lädt. Die im iframe geladene Seite versucht dann, eine Ajax-Anfrage an http://127.0.0.1:49253/Handler/testCors.ashx zu senden und die Ausgabe in ihrer eigenen Kopie des testCorsDiv div anzuzeigen.

Solange der Sandboxed iframe allow-scripts hat, funktioniert das wie ein Charme. Die iframe erzeugt ein OPTIONS Anfrage wie folgt aussehen (von Fiddler, mit Chrome getestet):

OPTIONS http://127.0.0.1:49253/Handler/testCors.ashx HTTP/1.1 
Host: 127.0.0.1:49253 
Connection: keep-alive 
Cache-Control: max-age=0 
Access-Control-Request-Method: GET 
Origin: null 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90  Safari/537.36 
Access-Control-Request-Headers: accept, x-requested-with 
Accept: */* 
Referer: http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: fi-FI,fi;q=0.8,en-US;q=0.6,en;q=0.4 

Mein testCors.ashx Handler dann einige Header ausspuckt, die besagt, dass das sieht ay-ok und der Browser folgt dann nach oben mit einem GET und es funktioniert einfach.

Die testCors.ashx tut dies:

public void ProcessRequest(HttpContext context) 
{ 
    context.Response.ContentType = "text/plain"; 
    context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 
    context.Response.AppendHeader("Access-Control-Allow-Headers", "content-type, x-requested-with, accept"); 
    context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS, GET"); 
    context.Response.Write("Hello World"); 
} 

So meinen Tests legen nahe, dass es möglich sein sollte, zu tun, was Sie wollen. Eine Sache jedoch, die ein Problem sein könnte, ist, wenn Ihr Handler nur für authentifizierte/autorisierte Benutzer zugänglich ist. Wie Sie sehen können, hat die OPTIONS Anfrage kein Cookie an den Handler gesendet. Auf der anderen Seite sagt Ihre Frage, dass die Antwort auf Ihre Optionen-Anfrage Status Code:200 ist. Ich nehme an, das wäre etwas 4**, wenn ein erforderliches Authentifizierungs-Cookie fehlte.

Ich schreibe auf, ich weiß nicht wirklich, was in Ihrem Fall falsch ist, aber vielleicht (?) Kann meine einfache Beispielseite Ihnen einige Hinweise geben, die Ihnen helfen, das Problem selbst zu finden.

+0

Vielen Dank, mit Ihrem Beispiel habe ich es geschafft, das Problem einfach neu zu erstellen, und dann mit einigen Optimierungen hat es funktioniert! –

+0

@TomGullen Froh, dass meine Antwort hilfreich war. Und danke für die Belohnung, schätze es, auch wenn ich nicht sicher bin, dass ich es verdient habe, da ich dein Problem nicht wirklich gelöst habe ... – user1429080

1

Stellen Sie sicher, dass IIS-Einstellung OPTION für diesen Handler zulässt - bereitgestellt in App mit App-Pool-Name "Web-App" und entsprechende Handler-Zuordnung sollte OPTION Anfrage ermöglichen.

Im Folgenden sind die Schritte, um dies zu tun.

  • erforderlich wählen AppPool
  • Klicken Sie auf Handler Mappings
  • select * .ashx und doppelklicken Sie auf den entsprechenden Handler, klicken Sie auf Anfrage Einschränkung, sehen, wenn Sie es Option Verb haben, wenn nicht, fügen hinzu, dass .

oben hier erwähnt - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/

Sie können folgenden Code verwenden müssen.

public void ProcessRequest (HttpContext context) { 
    context.Response.ContentType = "text/plain"; 
    context.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
    // You can try adding requested origin here instead of * like this - Request.Headers["Origin"] or only the specific domain, in your case it is -https://127.0.0.1:112 
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
    { 
     context.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE"); 
     context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
     context.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
    } 
    context.Response.Write(Token.CreateToken()); 
} 

Ich habe dies in my blog erklärt. Dies war für WCF, aber es sollte auch für Ihren Fall funktionieren! Sie müssen möglicherweise * für den erlaubten Ursprung in den angeforderten Ursprung ändern, da * ein Sicherheitsproblem vorliegt und alle Domänen CORS-Aufrufe vornehmen können.

+0

Alle meine ASHX-Handler haben das OPTION-Verb, und ich habe den obigen Code verwendet. Es funktioniert immer noch nicht! 'Kein 'Access-Control-Allow-Origin'-Header ist auf der angeforderten Ressource vorhanden. Herkunft 'Null' ist daher nicht erlaubt. " –

+0

Dies könnte ein dummer Vorschlag sein, können Sie versuchen,' null' anstelle von '*' hinzuzufügen? –

+0

Kein Glück, der gleiche Fehler. –

0

Können Sie versuchen, den folgenden Code in sowohl Ihrer HTML-und iFrame-Seite (in der HTML-DOC) hinzufügen und überprüfen, ob es funktioniert?

<script>document.domain = 'myDomain.com'</script> 

Hinweis: Bitte ersetzen Sie die ‚myDomain‘ mit entsprechenden Domain-Namen der Domain, die Sie verwenden (den Ursprung)

0

Anfragen AJAX machen scheint aus einer Sandbox iframe ohne allow-same-origin Option absolut unmöglich.

Sehen Sie diese Antwort für eine ausführliche Erklärung: IFRAME sandbox attribute is blocking AJAX calls

Aber ich bin darüber nicht ganz überzeugt. Bevor Sie aufgeben, vergewissern Sie sich, dass Ihr Server AJAX-Anfragen von einem anderen Hostnamen ohne Sandboxing akzeptiert (dh wenn er CORS unterstützt).

Für weitere Informationen über CORS sehen: http://www.html5rocks.com/en/tutorials/cors/

0

Der Fehler Sie bekommen:

XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 

ist, weil Ihre Anwendung von den Clickjacking-Angriffen gesichert wurde. In Ihrem Fall X-Fame-Options in Ihrer Anwendung web.config ist wahrscheinlich auf Deny gesetzt, Einstellung auf "SAMEORIGIN" würde helfen, Ihr Problem zu beheben, vorausgesetzt, Sie haben Ihre Anwendung hat die gleiche Domain wie Ihre iframe. Dies ist

, wie ihre getan:

<system.webServer> 
     <httpProtocol> 
     <customHeaders> 
      <add name="X-Frame-Options" value="SAMEORIGIN" /> 
     </customHeaders> 
     </httpProtocol> 
</system.webServer> 

Wenn Sie diese eine Arbeit um finden können (ich meine Anwendung Arbeit in iframe machen mit Deny Option gesetzt), dann wäre es einzig den Zweck vereiteln (Sicherheit gegen Clickjacking) eines solchen Features.

Hoffe, das hilft.

Verwandte Themen