2013-03-19 78 views
1

這裏是我想要做的(失敗,我可以補充),並希望你能給我文件上傳到一個跨域WCF服務的使用jQuery AJAX

從我的HTML5網站的任何方向,我想將文件上載到IIS 7.5中承載的跨域WCF服務。

除了上傳文件,我需要發送附加參數上傳功能的服務器

上這是可能的嗎?

這裏是我的OperationContract的樣子:

[OperationContract] 
[WebInvoke(Method = "POST", 
UriTemplate = "/uploadmodeldata/?id={Id}&customerdatatype={customerdatatype}&data={data}")] 
void UploadModelData(string Id, string customerdataType, byte[] data); 

這裏是我的jQuery Ajax請求

function FileVisits() { 

    var uid = checkCookie1(); 
    userid = uid.toString().replace(/"/g, ''); 
    var fileData = JSON.stringify({ 
    Id:userid ,customerdatatype:scanupload, 
     data: $('#fileBinary').val() 
    }); 
    alert(fileData); 
     "use strict"; 
     var wcfServiceUrl = "http://xxxxx:1337/Service1.svc/XMLService/"; 
     $.ajax({ 
      cache: false, 
      url: wcfServiceUrl + "uploadmodeldata/",    
      data: fileData, 
      type: "POST", 
      processData: false, 
      contentType: "application/json", 
      timeout: 10000, 
      dataType: "json", 
      headers: { 
         'User-agent': 'Mozilla/5.0 (compatible) Greasemonkey', 
         'Accept': 'application/atom+xml,application/xml,text/xml', 
        }, 
      beforeSend: function (xhr) { 
       $.mobile.showPageLoadingMsg(); 

       xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 


      }, 
      complete: function() { 
       $.mobile.hidePageLoadingMsg(); 
      }, 

      success: function (data) { 
       var result = data; 


      }, 
      error: function (data) { 
       alert("Error"); 
      } 
     }); 

} 

如果文件大小小於100 KB這個錯誤發生

方法不允許

但如果文件大於100 KB這個錯誤發生

413請求實體大

如何從jQuery的AJAX文件上傳到跨域WCF。 謝謝

回答

0

你得到Method not allowed因爲你正試圖調用另一個域上的服務。這違反了Same origin policy。這是一個安全限制。大多數舊版瀏覽器都會拒絕這些請求。

如果你想在javascript中訪問不同的域web服務,你將需要設置Cross-Origin Resource Sharing

跨源資源共享(CORS)是一種機制,允許web頁面將XMLHttpRequests創建到另一個域。這種「跨域」請求在其他情況下可能會被網頁瀏覽器禁止,即按照相同的 原始安全策略。 CORS定義了一種在瀏覽器和 服務器可以進行交互,以確定是否允許 跨域請求

如果你有機會到web服務代碼,就可以使在服務器CORS請求。
Enable cors是一個很好的資源。這裏有一些explaination on cors

在IIS 7上,您需要在web.config中設置一些自定義標頭。

<system.webserver> 
<httpprotocol> 
    <customheaders> 
    <add name="Access-Control-Allow-Origin" value="*" /> 
    <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
    </customheaders> 
</httpprotocol> 
</system.webserver> 

Here are the steps for IIS6

至於413錯誤,這是關係到最大文件大小,你讓你的綁定

<bindings> 
    <webHttpBinding> 
     <binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" /> 
    </webHttpBinding> 
</bindings> 
+0

解決此問題。其實我已經在wcf config中使用了綁定名稱。刪除綁定名稱後,每件事情都正常工作。 – MindFresher 2013-03-20 06:00:28

1

我花了大量的工作,但這裏是我的代碼(如果有人需要它):

$("#UploadFileBtn").click(function() {  
    fileName = document.getElementById("filePicker").files[0].name; 
    fileSize = document.getElementById("filePicker").files[0].size; 
    fileType = document.getElementById("filePicker").files[0].type;  
    var file = document.getElementById("filePicker").files[0]; 
    if (file) { 
    // create reader 
    var reader = new FileReader(); 
    reader.readAsDataURL(file); 
    reader.onload = function(e) { 
     var content = e.target.result; 
     content = content.substring(content.indexOf('64') + 3); 
     bhUploadRequest = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " + 
              "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " + 
              "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + 
              "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" + 
          "<SOAP-ENV:Header>"+ 
           "<m:FileName xmlns:m=\"http://tempuri.org/\">" + fileName + "</m:FileName>" + 
           "<m:Length xmlns:m=\"http://tempuri.org/\">" + fileSize + "</m:Length>" + 
          "</SOAP-ENV:Header>" + 
          "<SOAP-ENV:Body>" + 
           "<m:RemoteFileInfo xmlns:m=\"http://tempuri.org/\">" + 
            "<m:FileByteStream>" + content + "</m:FileByteStream>" + 
           "</m:RemoteFileInfo>" + 
          "</SOAP-ENV:Body>" + 
         "</SOAP-ENV:Envelope>"; 

     $.ajax({ 
      type: "POST", 
      async: true, 
      url: wsFtransferUrl, 
      data: bhUploadRequest, 
      timeout: 10000, 
      contentType: "text/xml", 
      crossDomain: true, 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader("SOAPAction", "http://tempuri.org/IFileTransferService/UploadFile"); 
       xhr.setRequestHeader("TICKET", Ticket); 
      },    
      success: function (data) { 
      alert('succes'); 
       $(data).find("UploadFileResponse").each(function() { 
        alert($(this).find("UploadFileResult").text()); 
       }); 
      }, 
      error: function (xhr, status, error) { 
       alert('error:' + error); 
      } 
     }); 

    }; 
} 
    return; 

    }); 

這裏是我的WCF傳輸服務:

public void UploadFile(RemoteFileInfo request) 
     { 
      string filePath = string.Empty; 
      string guid = Guid.NewGuid().ToString(); 
      int chunkSize = 1024; 
      byte[] buffer = new byte[chunkSize]; 
      long progress = 0; 

      filePath = Path.Combine(uploadFolder, request.FileName); 

      if (File.Exists(filePath)) 
       File.Delete(filePath); 

      using (FileStream writeStream = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write)) 
      { 
      do 
       { 
        // read bytes from input stream 
        int bytesRead = request.FileByteStream.Read(buffer, 0, chunkSize); 
        if (bytesRead == 0) 
         break; 
        progress += bytesRead;      
        // write bytes to output stream 
        writeStream.Write(buffer, 0, bytesRead); 
       } 
       while (true); 
      } 
     } 
+0

請給你的代碼添加一些解釋。 – 2015-01-23 11:48:38

0

問題出在「POST」。要解決該問題,請執行以下操作:

創建Global.asax並添加以下內容以啓用Ajax跨域POST。

public void Application_BeginRequest(object sender, EventArgs e) 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST,OPTIONS"); 

      if ((HttpContext.Current.Request.HttpMethod == "OPTIONS")) 
      { 

       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
       HttpContext.Current.Response.End(); 
      } 
     } 
    }