js實現非同步跨域上傳
阿新 • • 發佈:2019-02-20
無聊寫點東西,希望對一些朋友有用,先上程式碼
這是前端程式碼
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="jquery.js"></script> </head> <body> <form class="myform" action="http://127.0.0.1:8080/jfinalDemo/music/upload" method="post" enctype="multipart/form-data"> <input type="file" class="uploadFile" name="file"/> <input type="button" class="upload" value="上傳"/> </form> </body> <script> //以jquery外掛的形式寫 (function() { var iframe = '<iframe name="jqUploadIframe" style="display: none"></iframe>'; function getSearchObjct(window) { var search; try{ search = window.location.search.substr(1); }catch (e){ return null; } if(search == "") return ""; var keyValue = search.split("&"); var result = {}; for(var i = 0; i<keyValue.length; i++) { var onek = keyValue[i].split("="); result[onek[0]] = decodeURI(onek[1]); } return result; } function getRootPath(){ var curWwwPath=window.document.location.href; var pathName=window.document.location.pathname; var pos=curWwwPath.indexOf(pathName); var localhostPaht=curWwwPath.substring(0,pos); var projectName=pathName.substring(0,pathName.substr(1).indexOf('/')+1); return(localhostPaht+projectName); } var methods = { //跨域上傳 crossDomain: function(op) { this.attr("target", "jqUploadIframe"); var $iframe = $(iframe); var val = "window.location.href='"+getRootPath()+"/jqUpload32495982348952?data=massage'"; this.append('<input type="hidden" class="jqUpload-localhostname" ' + 'name="uploadCall" value="'+val+'"/>'); $iframe[0].onload = function() { var searchData = getSearchObjct(this.contentWindow); if(searchData == "") { return ; } else if(searchData == null) { op.error(searchData.data); } else if(typeof searchData == "object") { op.success(searchData.data); } $iframe.remove(); $(".jqUpload-localhostname").remove(); } this.append($iframe); this.submit(); } } $.fn.jqAjaxUpload = function(op) { methods.crossDomain.apply(this, [op]) } })() //當點選上傳按鈕時 $(".upload").click(function() { //呼叫非同步跨域上傳功能 $(".myform").jqAjaxUpload({ isCrossDomain: true, success: function(data) { console.log("我的資料:"+data); }, error: function() { console.log("錯誤了"); } }) }) </script> </html>
後臺使用的java的jfinal框架
<pre name="code" class="java">public void upload() { //儲存檔案 getFile("file"); //這是返回資訊 String returnMessage = "成功了"; //這裡傳回頁面的資訊必須是如下格式前端會自動傳到後臺一個uploadCall的引數,返回一段可執行的js程式碼,所以是renderHtml renderHtml("<script>"+getPara("uploadCall").replace("massage", returnMessage)+"</script>"); }
示例圖片
選擇檔案上傳,成功了
原理其實很簡單,由於要非同步上傳檔案,我使用了隱藏的iframe來提交表單,這樣頁面就不會重新整理,但是如果後臺直接返回訊息,前臺由於跨域不能獲取iframe中的內容,所以我們後臺返回了一點js程式碼,除錯你會發現引數uploadCall是一個跳轉語句,也就是我們返回到前臺的語句又進行了跳轉,而跳轉的頁面就是我們前臺域的頁面,上圖的404連結,因為我們沒有這個頁面,所以報了404,當然我們也不需要這個頁面,因為我們需要的連結後的data引數,既然是同一個域了,我們也就可以獲取iframe的window.location.search了,自然就拿到了我們的後臺返回訊息