2015-04-14 26 views
9

Tôi có một trang ascxGetToken.ashx.Tiêu đề không được đặt cho OPTIONS Yêu cầu Ajax

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

Khi tôi AJAX trang này, nó sẽ trả về các tiêu đề sau:

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 

Khi trang mà làm theo yêu cầu AJAX được đặt trong một iFrame sandboxed, nó hiển thị lỗi:

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. 

Và trả về tiêu đề:

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 

Tôi dường như không nhận được yêu cầu OPTIONS để thêm tiêu đề. Thêm allow-same-origin vào thuộc tính hộp cát sẽ thay đổi yêu cầu thành GET, nhưng tôi không muốn cấp cho iFrame các quyền đó.

Trả lời

6

Tôi cho rằng bạn có nghĩa là để viết ashx, không ascx. Sự hiện diện của phương thức ProcessRequest (HttpContext context) cho thấy đó là một trình xử lý chung và không phải là điều khiển người dùng.

Tôi đã thực hiện một trang rất đơn giản để thử nghiệm với:

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

tôi tải trang trên http://localhost:49253/SandboxTest.aspx. Sau đó, trang thực hiện yêu cầu ajax tới http://localhost:49253/Handler/testCors.ashx và đặt kết quả đầu ra từ đó vào số testCorsDiv div. Điều này tạo ra một GET thẳng cho trình xử lý (vì nó đến từ cùng một nguồn gốc) và đầu ra được chèn vào.

Trong trang cũng là hộp cát iframe tải cùng một trang bằng url http://127.0.0.1:49253/SandboxTest.aspx. Các ?sandboxed=true là có để ngăn chặn các iframe từ đệ quy tải một iframe bên trong. Sau đó, trang được tải trong khung nội tuyến sẽ cố gắng thực hiện yêu cầu ajax đến http://127.0.0.1:49253/Handler/testCors.ashx và hiển thị đầu ra trong bản sao riêng của nó là div testCorsDiv.

Miễn là khung nội tuyến có hộp cát có allow-scripts, nó hoạt động như một nét duyên dáng. Các iframe tạo ra một OPTIONS yêu cầu tìm kiếm như thế này (từ Fiddler, thử nghiệm với 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 

handler testCors.ashx của tôi sau đó khạc nhổ ra một số tiêu đề mà nói rằng điều này có vẻ ay-ok và trình duyệt rồi sau lên với một GET và nó chỉ hoạt động.

Các testCors.ashx thực hiện điều này:

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

Vì vậy, thử nghiệm của tôi cho thấy rằng chúng ta có thể làm những gì bạn muốn. Một điều mặc dù đó có thể là một vấn đề là nếu trình xử lý của bạn chỉ có thể truy cập được đối với người dùng được xác thực/ủy quyền. Như bạn có thể thấy yêu cầu OPTIONS chưa gửi cookie tới trình xử lý. Nhưng mặt khác câu hỏi của bạn nói rằng phản ứng với yêu cầu tùy chọn của bạn là Status Code:200. Tôi cho rằng đó sẽ là một số 4** nếu thiếu cookie xác thực bắt buộc.

Kết thúc, tôi thực sự không biết có gì sai trong trường hợp của bạn, nhưng có thể (?) Trang mẫu đơn giản của tôi có thể cung cấp cho bạn một số manh mối giúp bạn tự tìm ra vấn đề.

+0

Cảm ơn bạn, bằng cách sử dụng ví dụ của bạn tôi quản lý để tái tạo các vấn đề đơn giản, và sau đó với một số tinh chỉnh có nó làm việc! –

+0

@TomGullen Rất vui khi câu trả lời của tôi là giúp đỡ. Và cảm ơn vì tiền thưởng, đánh giá cao nó ngay cả khi tôi không chắc chắn rằng tôi xứng đáng vì tôi đã không thực sự giải quyết vấn đề của bạn ... – user1429080

1

Đảm bảo bạn có cài đặt IIS để cho phép OPTION xử lý đó - được triển khai cho ứng dụng có tên Ứng dụng web "ứng dụng web" và ánh xạ trình xử lý tương ứng phải cho phép yêu cầu OPTION.

Sau đây là các bước để thực hiện điều đó.

  • chọn cần thiết ứng dụng hồ bơi
  • Bấm vào ánh xạ xử lý
  • chọn * ashx và kích đúp vào xử lý tương ứng, bấm vào Yêu cầu hạn chế, xem nếu bạn có tùy chọn động từ ở đó, nếu không muốn nói, thêm rằng .

Trên đề cập ở đây - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/

Bạn có thể cần phải sử dụng mã sau đây.

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

Tôi đã giải thích điều này trong my blog. Điều này là dành cho WCF, nhưng nó cũng làm việc cho trường hợp của bạn! Bạn có thể cần phải thay đổi * cho nguồn gốc được phép theo yêu cầu, vì * có vấn đề về bảo mật, nó cho phép tất cả các miền thực hiện cuộc gọi CORS.

+0

Tất cả các trình xử lý ASHX của tôi đều có động từ OPTION và tôi đã sử dụng mã ở trên. Nó vẫn không hoạt động! Không có tiêu đề 'Không' Access-Control-Allow-Origin 'trên tài nguyên được yêu cầu. Do đó, không cho phép xuất xứ 'null'.. –

+0

Đây có thể là một gợi ý ngớ ngẩn, bạn có thể thử thêm 'null' vào vị trí' * 'không? –

+0

Không may mắn, lỗi tương tự. –

0

Bạn có thể thử thêm mã bên dưới vào cả trang HTML và iFrame (trong DOC HTML) và kiểm tra xem nó có hoạt động không?

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

Lưu ý: Xin vui lòng thay thế 'mydomain' bằng tên miền thích hợp của tên miền mà bạn đang sử dụng (nguồn gốc)

0

Làm yêu cầu AJAX dường như là hoàn toàn không thể từ một iframe sandbox mà không có sự lựa chọn allow-same-origin.

Xem câu trả lời này cho một lời giải thích chi tiết: IFRAME sandbox attribute is blocking AJAX calls

Tuy nhiên, tôi không hoàn toàn thuyết phục về nó. Trước khi từ bỏ, hãy đảm bảo rằng máy chủ của bạn chấp nhận các yêu cầu AJAX từ một tên máy chủ khác không có hộp cát (ví dụ: nếu nó hỗ trợ CORS).

Đối với thông tin thêm về CORS xem: http://www.html5rocks.com/en/tutorials/cors/

0

Các lỗi bạn đang nhận được:

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. 

là vì ứng dụng của bạn đã được bảo đảm từ các cuộc tấn công clickjacking. Trong trường hợp của bạn X-Fame-Options trong web.config ứng dụng của bạn có thể được đặt thành Deny, đặt thành 'SAMEORIGIN' sẽ giúp khắc phục sự cố của bạn, miễn là bạn có đơn đăng ký có cùng tên miền với iframe.

Đây là cách làm của nó:

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

Nếu bạn có thể tìm thấy một công việc xung quanh cho điều này (tôi có nghĩa là làm cho công việc ứng dụng của bạn trong iframe với Deny tùy chọn thiết lập), sau đó nó sẽ đánh bại mục đích duy nhất (an ninh chống lại clickjacking) có tính năng như vậy.

Hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan