標籤:add image 字元 tty original 若是 重新整理 reader blog
之前工作中遇到了表單跨域上傳的問題,尋覓了挺久,才找到解決方案,在此記錄。
一、使用from表單上傳
工作原理:直接表單提交,訪問ssc_media的對應介面
架構說明:使用的是SpringBoot微服務架構,ssc_web負責前端頁面和實現對應的後台介面。 ssc_media負責把圖片和檔案上傳到mongodb。
${temp}:使用了thymeleaf模組,是一個url路徑,指向ssc_media模組的上傳檔案介面。
<body>
<!--直接調用media模組的介面--><form id= "uploadForm" th:action= "${temp}" method= "post" enctype ="multipart/form-data"> <h1 >測試通過Rest介面上傳檔案 </h1> <p >上傳檔案: <input type ="file" name="file" /></p> <input type ="submit" value="上傳"/></form>
</body>
當點擊“上傳”按鈕時,會採用“表單提交”方式上傳圖片,跳轉到ssc_media模組的相關介面。
缺點是:“表單提交”方式上傳成功後,會重新整理頁面。本項目要求:頁面局部重新整理。
二、ajax提交
工作原理:把ssc_web的後台介面當中介層,轉寄檔案流到ssc_media的相關介面
html:
<body>
<!--直接調用media模組的介面-->
<form id= "uploadForm" enctype ="multipart/form-data">
<p >上傳檔案: <input type ="file" name="file"/></p>
<input type="button" value="上傳" onclick="doUpload()"/>
</form>
<script language="JavaScript">
<![CDATA[
function doUpload() { var formData = new FormData($( "#uploadForm" )[0]); $.ajax({ url: "/web/retailer/lotus/outlet/014/uploadDmImg/1" , type: ‘POST‘, data: formData, async: false, cache: false, contentType: false, processData: false, success: function (returndata) { var obj = eval(‘(‘ + returndata + ‘)‘); alert(obj.data.image); }, error: function (returndata) { alert("no"); } });}]]></script></body>
ssc_web的DmController.java:
/** * 上傳圖片 * @param retailerCode * @param outletExternalId * @param dmId * @throws IOException */ @RequestMapping(value = "/{retailerCode}/outlet/{outletExternalId}/uploadDmImg/{dmId}", method = RequestMethod.POST ) @ResponseBody public String uploadDmImg(@PathVariable("retailerCode") String retailerCode, @PathVariable("outletExternalId") String outletExternalId, @PathVariable("dmId") Long dmId,@RequestParam("file") MultipartFile multipartFile) throws IOException { String url = "http://172.19.155.33:9999/media/image/uploadDm?retailerCode="+retailerCode+"&isThumbnail=false&outletExternalId="+outletExternalId+"&dmId="+dmId; return postFile(url,multipartFile); }
//拼要求標頭,ssc_media的介面要求接收MultipartFile類型檔案 public String postFile(String urlStr,MultipartFile multipartFile) throws IOException { String end = "\r\n"; String twoHyphens = "--"; String boundary = "******"; URL url = new URL(urlStr); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); httpURLConnection.setConnectTimeout(30000); // 必須在Content-Type要求標頭中指定分界符中的任一字元串 httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); //擷取輸出資料流對象,預備上傳檔案 DataOutputStream dos = new DataOutputStream(httpURLConnection .getOutputStream()); //設定分界符,加end表示單獨一行 dos.writeBytes(twoHyphens + boundary + end); //設定與上傳檔案相關的資訊 String filename = multipartFile.getOriginalFilename(); dos.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + filename.substring(filename.lastIndexOf("/") + 1) + "\"" + end); //在上傳檔案資訊與檔案的內容之間必須有一個空行 dos.writeBytes(end); InputStream fis = multipartFile.getInputStream(); byte[] buffer = new byte[8192]; // 8k int count = 0; while ((count = fis.read(buffer)) != -1) { dos.write(buffer, 0, count); } fis.close(); dos.writeBytes(end); dos.writeBytes(twoHyphens + boundary + twoHyphens + end); dos.flush(); InputStream is = httpURLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br = new BufferedReader(isr); String result = br.readLine(); System.out.println("result = " + result); dos.close(); is.close(); return result; }
ssc_meida的ImageControlle.java:
@RequestMapping(value = "/uploadDm", method = RequestMethod.POST) public RspVo<DmImageInfoVo> uploadDm(String retailerCode, String outletExternalId, Long dmId, Boolean isThumbnail, @RequestParam("file") MultipartFile file) { //實現邏輯。。。。。。。。 }
額外話題:
1、若要局部重新整理頁面,必須是:
<input type="button" value="確定" />
若是:
<button value="確定" />或者<input type="submit" value="確定" />
會重新整理頁面。
問題集錄02--檔案上傳(可跨域)