【问题标题】:File Upload to a cross domain WCF service using jquery ajax使用 jquery ajax 将文件上传到跨域 WCF 服务
【发布时间】:2013-03-19 11:39:28
【问题描述】:

这是我正在尝试做的事情(不成功,我可能会补充),并希望您能给我任何指导

从我的 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。 谢谢

【问题讨论】:

    标签: c# jquery asp.net html wcf


    【解决方案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);
                }
            }
    

    【讨论】:

      【解决方案2】:

      您收到Method not allowed 是因为您尝试调用另一个域上的服务。这违反了Same origin policy。这是一个安全限制。大多数旧浏览器会拒绝此类请求。

      如果你想在 javascript 中访问不同的域 web 服务,你需要设置 Cross-Origin Resource Sharing

      跨域资源共享 (CORS) 是一种允许网络 页面向另一个域发出 XMLHttpRequests。这样的“跨域” 否则,请求将被 Web 浏览器禁止,同样 源安全策略。 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>
      

      【讨论】:

      • 解决这个问题。实际上我在 wcf 配置中使用了绑定名称。删除绑定名称后,一切正常。
      【解决方案3】:

      问题在于“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();
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-24
        • 2012-04-23
        • 1970-01-01
        • 1970-01-01
        • 2012-01-30
        • 2011-12-30
        • 2016-10-22
        • 2012-06-11
        相关资源
        最近更新 更多