文件跨域传输
用Java springMVC直接上传代码很简单。由于我们系统已经是web与api两个分开的系统,所以以前上传文件是先在web端解析为json的然后再用httpclient发到api。直到昨天发现一个问题,几MB的文件就传不过去了,经排查定位问题在于HttpClient不支持这么大的内容传输(NameValuePair)
我的第一个解决方案是在页面直接上传文件到api,也就是跨域上传文件。http是行得通的,代码是这样,在进入页面的代码设置response.header:
//设置上传路径 request.setAttribute("uploadUrl", uploadHost+"/xx/xx"); //如果需要把Cookie发到服务端,需要指定Access-Control-Allow-Credentials字段为true; response.setHeader("Access-Control-Allow-Credentials", "true"); //允许跨域的域名,*号为允许所有,存在被 DDoS攻击的可能。 response.setHeader("Access-Control-Allow-Origin","*"); //表明服务器支持的头信息字段 response.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");上传时的javascript代码:
let formData=new FormData(); formData.append("file",$('#uploadFile')[0].files[0]); formData.append("name",$("input[name='name']").val()); $.ajax({ url: uploadUrl,//上传地址 type: 'POST', cache: false, crossDomain:true, //设置跨域为true xhrFields: { withCredentials: true //默认情况下,标准的跨域请求是不会发送cookie的 }, data: formData,//表单数据 processData: false, contentType: false, dataType:"json", success:function(data){ } });本来就这么简单,但一上测试环境就发现前端报错:
已阻止载入混合活动内容
查资料发现,是因为页面用的是HTTPS协议,而uploadUrl是http协议。
好嘛,我把uploadUrl改成http的。再试,又报:
CORS 请求未成功
这就成死循环了,用https不能跨域,不用https又不能http与https混用。只能再改方案。HttpClient中转文件.
pom.xml配置:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.1.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.1.3</version> </dependency>上传代码:
public String sendFileByHttpClient(HttpServletRequest request,String url,MultipartFile file,Map<String,String> vals) { HttpClient httpclient = new DefaultHttpClient(); String result = null; try { String key = cookieUtils.getCookieValue(request, "key"); HttpPost httppost = new HttpPost(url); File uploadFold=new File(System.getProperty("java.io.tmpdir")+File.separator+"uploadFold"); if(!uploadFold.exists()) { uploadFold.mkdirs(); } File tmpFile=new File(System.getProperty("java.io.tmpdir")+File.separator+"uploadFold"+File.separator+file.getName()); file.transferTo(tmpFile); httppost.addHeader("Cookie", "key=" + key); MultipartEntity reqEntity = new MultipartEntity(); reqEntity.addPart("file", new FileBody(tmpFile)); for(Entry<String,String> entry:vals.entrySet()) { reqEntity.addPart(entry.getKey(),new StringBody(entry.getValue())); } httppost.setEntity(reqEntity); HttpResponse response = httpclient.execute(httppost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { return EntityUtils.toString(resEntity, "UTF-8"); } } return result; } catch (Exception e) { logger.error(e.getMessage(),e); return result; } finally { try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) { } } }
相关阅读
评论:
↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑