2015-04-14 65 views
9

Mam ascx strona GetToken.ashx.Nagłówek nie jest ustawiony na OPCJE Ajax request

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

Kiedy AJAX na tej stronie, to zwraca następujące nagłówki:

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 

Gdy strona sprawia, że ​​żądania AJAX jest umieszczona w piaskownicy iFrame, pokazuje błąd:

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. 

i zwraca nagłówki:

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 

Nie mogę uzyskać żądania OPTIONS, aby dodać nagłówek. Dodanie allow-same-origin do właściwości piaskownicy zmienia żądanie na GET, ale nie chcę udzielać tych iFrame tych uprawnień.

Odpowiedz

6

Zakładam, że masz na myśli napisać ashx, nie ascx. Obecność metody ProcessRequest (HttpContext context) sugeruje, że jest to ogólny program obsługi, a nie kontrola użytkownika.

zrobiłem bardzo prostą stronę do przetestowania z:

<%@ 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> 

załadować stronę na http://localhost:49253/SandboxTest.aspx. Strona następnie wysyła żądanie ajax do http://localhost:49253/Handler/testCors.ashx i umieszcza na nim dane wyjściowe w jednostce div testCorsDiv. Generuje to prostą GET do obsługi (ponieważ pochodzi z tego samego pochodzenia), a wyjście zostaje wstawione.

Na stronie znajduje się również piaskownica iframe, która ładuje tę samą stronę przy użyciu adresu URL http://127.0.0.1:49253/SandboxTest.aspx. Numer ?sandboxed=true uniemożliwia elementowi iframe ładowanie rekursywne wewnętrznego elementu iframe. Strona wczytana w ramce iframe następnie spróbuje wysłać żądanie ajax do http://127.0.0.1:49253/Handler/testCors.ashx i wyświetlić wyjście w swojej własnej kopii elementu testCorsDiv div.

Tak długo jak piaskownica iframe ma allow-scripts działa to jak czar. iframe generuje OPTIONS wniosek patrząc tak (z Skrzypek, przetestowane z Chrome):

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 

Moja testCors.ashx obsługi następnie wypluwa kilka nagłówków, które mówi, że wygląda to ay-ok, a przeglądarka następnie śledzi z GET i po prostu działa.

testCors.ashx robi to:

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"); 
} 

Więc moje badania sugerują, że powinno być możliwe, aby robić to, co chcesz. Jedną z rzeczy, która może być problemem jest to, że twój przewodnik jest dostępny tylko dla uwierzytelnionych/autoryzowanych użytkowników. Jak widać, żądanie OPTIONS nie wysłało pliku cookie do programu obsługi. Ale z drugiej strony twoje pytanie mówi, że odpowiedź na twoje pytanie o opcje to Status Code:200. Przypuszczam, że byłby to jakiś numer 4**, gdyby brakowało wymaganego pliku cookie uwierzytelniającego.

Podsumowując, tak naprawdę nie wiem, co jest nie tak w twoim przypadku, ale może (?) Moja prosta przykładowa strona może dostarczyć ci wskazówek, które pomogą ci znaleźć problem.

+0

Dziękuję, korzystając z tego przykładu, udało mi się w prosty sposób odtworzyć problem, a następnie z pewnymi zmianami działało! –

+0

@TomGullen Cieszę się, że moja odpowiedź była pomocna. I dziękuję za nagrodę, doceń to, nawet jeśli nie jestem pewien, czy zasłużyłem na to, ponieważ tak naprawdę nie rozwiązałem twojego problemu ... – user1429080

1

Upewnij się, że masz ustawienia IIS zezwalające na OPTION dla tego handler'a - wdrożone w aplikacji, która mówi, że nazwa puli aplikacji "web-app" i odpowiadające mapowanie obsługi powinny zezwalać na OPTION żądanie.

Poniżej przedstawiono kroki, aby to zrobić.

  • Wybierzcie wymagany puli aplikacji
  • Kliknij odwzorowań procedur obsługi
  • select * .ashx i kliknij dwukrotnie na odpowiedniej obsługi, kliknij na życzenie ograniczenie, czy masz tam opcji czasownik, jeśli nie, należy dodać, że .

Powyżej wspomniano tutaj - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/

Może trzeba użyć następującego kodu.

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()); 
} 

Wyjaśniłem to w my blog. To było dla WCF, ale powinno działać również dla twojego przypadku! Być może trzeba zmienić * dla dozwolonego pochodzenia na żądane pochodzenie, ponieważ * ma problem z bezpieczeństwem, umożliwia wszystkim domenom wywoływanie CORS.

+0

Wszystkie moje programy obsługi ASHX mają czasownik OPCJA i użyłem powyższego kodu. Nadal nie działa! Nagłówek 'No 'Access-Control-Allow-Origin' jest obecny na żądanym zasobie. Pochodzenie 'null' jest zatem niedozwolone. " –

+0

To może być głupia sugestia, czy możesz spróbować dodać' null' zamiast '*? –

+0

Bez powodzenia, ten sam błąd. –

0

Czy możesz spróbować dodać poniższy kod na stronie zarówno strony HTML, jak i iFrame (w HTML DOC) i sprawdzić, czy działa?

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

Uwaga: Proszę wymienić „MojaDomena” z odpowiednią nazwę domeny, domeny, której używasz (pochodzenie)

0

Making żądań AJAX wydaje się absolutnie niemożliwe z piaskownicy iframe bez opcji allow-same-origin.

Zobacz tę odpowiedź za szczegółowe wyjaśnienie: IFRAME sandbox attribute is blocking AJAX calls

Jednak nie jestem przekonany o tym. Przed rezygnacją upewnij się, że twój serwer akceptuje żądania AJAX z innej nazwy hosta bez sandboxingu (np. Jeśli obsługuje CORS).

Aby uzyskać więcej informacji na temat CORS patrz: http://www.html5rocks.com/en/tutorials/cors/

0

Błąd swój otrzymujesz:

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. 

dlatego aplikacja zostały zabezpieczone przed atakami clickjacking. W twoim przypadku X-Fame-Options w aplikacji web.config jest prawdopodobnie ustawiony na Deny, ustawienie go na "SAMEORIGIN" pomoże rozwiązać problem, pod warunkiem, że Twoja aplikacja ma tę samą domenę co Twoja iframe.

ten sposób jej zrobić:

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

Jeśli jesteś w stanie znaleźć pracę wokół tego (to znaczy uczynić swoją pracę aplikacji w iframe z Deny zestaw opcji), wtedy byłoby pokonać jedyny cel (zabezpieczenie przed kliknięciem) o takiej funkcji.

Mam nadzieję, że to pomoże.

Powiązane problemy