问题集录02--文件上传(可跨域)

Posted tanwei81

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问题集录02--文件上传(可跨域)相关的知识,希望对你有一定的参考价值。

之前工作中遇到了表单跨域上传的问题,寻觅了挺久,才找到解决方法,在此记录。

 

一、使用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--文件上传(可跨域)的主要内容,如果未能解决你的问题,请参考以下文章

可跨域的单点登录(SSO)实现方案(附.NET代码)

偷懒小工具 - SSO单点登录通用类(可跨域)(上)

偷懒小工具 - 通用单点登录类(可跨域)

可跨域的单点登录(SSO)实现方案

高级篇javascript静态页面传值的三种方法 url方法,取值方便,可跨域; cookie方法,同源访问; window.open方法,指向父窗口

高级篇javascript静态页面传值的三种方法 url方法,取值方便,可跨域; cookie方法,同源访问; window.open方法,指向父窗口