2015-09-25 16 views
5

Vì vậy, tôi muốn POST tệp Tải lên cùng với AntiForgeryToken qua AJAX. Dưới đây là mã của tôi:Cách gửi AntiForgeryToken (CSRF) cùng với FormData qua jquery ajax

Xem

@using (Html.BeginForm("Upload", "RX", FormMethod.Post, new {id = "frmRXUpload", enctype = "multipart/form-data"})) 
{ 
    @Html.AntiForgeryToken() 
    @Html.TextBoxFor(m => m.RXFile, new {.type = "file"}) 
    ...rest of code here 
} 

<script> 
    $(document).ready(function(){ 
     $('#btnRXUpload').click(function() { 
      var form = $('#frmRXUpload') 

      if (form.valid()) { 
       var formData = new FormData(form); 
       formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); 
       formData.append('__RequestVerificationToken', fnGetToken()); 

       $.ajax({ 
        type: 'POST', 
        url: '/RX/Upload', 
        data: formData, 
        contentType: false, 
        processData: false 
       }) 
      } 
     }) 
    }) 
</script> 

khiển

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Upload() 
{ 
    //rest of code here 
} 

tôi nhận được

Các dấu hiệu chống giả mạo không thể được giải mã. Nếu ứng dụng này được lưu trữ bởi Trang web trên web hoặc cụm

lỗi thông qua fiddler. Bất kỳ ý tưởng làm thế nào để giải quyết vấn đề này?

Tôi tìm thấy ĐÁP:

<script> 
     $(document).ready(function(){ 
      $('#btnRXUpload').click(function() { 
       var form = $('#frmRXUpload') 

       if (form.valid()) { 
        var formData = new FormData(form.get(0)); //add .get(0) 
        formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); 

        $.ajax({ 
         type: 'POST', 
         url: '/RX/Upload', 
         data: formData, 
         contentType: false, 
         processData: false 
        }) 
       } 
      }) 
     }) 
    </script> 
+0

là gì 'fnGetToken() '? –

+0

Hành vi này có thay đổi nếu ứng dụng không được lưu trữ trên Trang web hoặc cụm không? Yêu cầu không ajax có hoạt động không? –

+0

@StephenMuecke: một chức năng để nhận được chuỗi mã thông báo – warheat1990

Trả lời

4

Cuối cùng tìm thấy câu trả lời:

Tôi chỉ cần thêm .get(0) vào biểu mẫu, đây là các mã:

<script> 
     $(document).ready(function(){ 
      $('#btnRXUpload').click(function() { 
       var form = $('#frmRXUpload') 

       if (form.valid()) { 
        var formData = new FormData(form.get(0)); //add .get(0) 
        formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); 
        //formData.append('__RequestVerificationToken', fnGetToken()); //remark this line 

        $.ajax({ 
         type: 'POST', 
         url: '/RX/Upload', 
         data: formData, 
         contentType: false, 
         processData: false 
        }) 
       } 
      }) 
     }) 
    </script> 
+0

$ (mẫu) .get (0) đã giúp tôi vượt qua ranh giới. Thanx mate !!! – Arjmand

3

Bạn cần phải thêm các thẻ vào tiêu đề yêu cầu, không phải là hình thức. Như thế này:

 if (form.valid()) { 
      var formData = new FormData(form); 
      formData.append('files', $('#frmRXUpload input[type="file"]')[0].files[0]); 

      $.ajax({ 
       type: 'POST', 
       url: '/RX/Upload', 
       data: formData, 
       contentType: 'multipart/form-data', 
       processData: false, 
       headers: { 
        '__RequestVerificationToken': fnGetToken() 
       } 
      }) 
     } 

Sửa Nhìn lại cách tôi giải quyết vấn đề này bản thân mình, tôi nhớ rằng ValidateAntiForgeryTokenAttribute chuẩn trông trong đối tượng Request.Form mà không phải lúc nào được dân cư cho một yêu cầu AJAX. (Trong trường hợp của bạn, việc tải lên tệp cần loại nội dung multipart/form-data, trong khi một biểu mẫu đăng cho mã thông báo CSRF cần application/x-www-form-urlencoded. Bạn đặt contentType=false, nhưng hai hoạt động cần loại nội dung xung đột, có thể là một phần của vấn đề của bạn). Vì vậy, để xác nhận các dấu hiệu trên máy chủ, bạn sẽ cần phải viết một thuộc tính tùy chỉnh cho phương pháp hành động của bạn để kiểm tra cho token trong tiêu đề yêu cầu:

public sealed class ValidateJsonAntiForgeryTokenAttribute 
          : FilterAttribute, IAuthorizationFilter 
{ 
    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext == null) 
     { 
      throw new ArgumentNullException("filterContext"); 
     } 

     var httpContext = filterContext.HttpContext; 
     var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
     AntiForgery.Validate(cookie != null ? cookie.Value : null, 
          httpContext.Request.Headers["__RequestVerificationToken"]); 
    } 
} 

Thông tin thêm (một chút ra khỏi ngày nay) here.

+0

Mã thông báo có thể được thêm vào 'FormData'. Nếu mã hiện tại của OP không hoạt động, thì sẽ không có điều này. –

+0

cuối cùng đã tìm thấy câu trả lời, kiểm tra bài đăng cập nhật của tôi. – warheat1990

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