文件跨域传输

用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) {

		}
	}

}

文/程忠 浏览次数:0次   2019-06-11 20:16:17

相关阅读


评论:
点击刷新

↓ 广告开始-头部带绿为生活 ↓
↑ 广告结束-尾部支持多点击 ↑