js XMLHttpRequest + FormData 跨域提交表单上传文件

时间:2022-08-29 08:50:17

 

funUploadFile : function(file){
	var self = this;  // 在each中this指向没个v  所以先将this保留
	var formdata = new FormData();
     formdata.append("index", file.index);
	formdata.append("fileList", file);	         		
	var xhr = new XMLHttpRequest();
	if ("withCredentials" in xhr) {
	// XHR for Chrome/Firefox/Opera/Safari.
	  xhr.open("POST", self.url, true);
	} else if (typeof XDomainRequest != "undefined") {
	// XDomainRequest for IE.
	    xhr = new XDomainRequest();
	    xhr.open("POST", self.url);
	} else {
	   xhr = null;
	}
	// 绑定上传事件
	// 进度
	xhr.upload.addEventListener('progress', function (e) {
	  if (e.lengthComputable) {
	  // 回调到外部
		self.onProgress(file, e.loaded, e.total);
	  }
	}, false); 
	// 完成
	xhr.addEventListener("load", function(e){
	// 从文件中删除上传成功的文件  false是不执行onDelete回调方法
	  self.funDeleteFile(file.index, false);
	  // 回调到外部
	  self.onSuccess(file, xhr.responseText);
	  if(self.uploadFile.length == 0){
	    // 回调全部完成方法
		self.onComplete("全部完成");
	  }
	}, false);
	xhr.addEventListener("error", function(e){
	  // 回调到外部
	  self.onFailure(file, xhr.responseText);
	}, false);
	//xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
	//xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
     //xhr.setRequestHeader("Content-Type", "multipart/form-data");
	xhr.send(formdata);
	//xhr.send();
	}

  

上述提交的html表单类似于:<form id="uploadForm" action="http://fileserver.bbb.com/fileserver.ashx?action=upload&aid=1" method="post" enctype="multipart/form-data">

 

后台配置:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <add name="handler" path="handler.ashx" verb="*" type="WebApp.handler"/>
      <remove name="OPTIONSVerbHandler" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
  </system.webServer>

  用handler后台处理:

namespace WebApp
{
    /// <summary>
    /// handler 的摘要说明
    /// </summary>
    public class handler : IHttpHandler
    {
        private HttpRequest _request;
        private HttpResponse _response;
        private HttpContext _context;

        public void ProcessRequest(HttpContext context)
        {
            _context = context;
            _request = context.Request;
            _response = context.Response;

            var action = context.Request.QueryString["action"];
            switch (action)
            {
                case "upload":
                    Upload();
                    break;
                default:
                    break;
            }
        }

        private void Upload()
        {
            if (_request.Files.Count > 0)
            {

            }
            _response.Write("aa:"+"xxx");
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

  

在跨域请求的过程中一共请求了两次,第一次是一个叫做preflight的options请求,发送给服务器让服务器确认是否接受跨域请求,然后返回给浏览器确认,然后进行第二次真正的请求。如下图所示:

js XMLHttpRequest + FormData 跨域提交表单上传文件

js XMLHttpRequest + FormData 跨域提交表单上传文件