我正在开发一个关于下载文件的html web应用程序。首先我点击下载按钮,浏览器显示一个提示,此时,它已经向我的服务器发送了一个请求。我得到如下所示的标题,但浏览器没有正确显示文件名。
===========================================
host: 192.168.0.101
remote_addr: 192.168.0.102
x-real-ip: 192.168.0.102
x-forwarded-for: 192.168.0.102
connection: close
cookie: JSESSIONID=DECD58D9A660FBA200BF7F920F9B7ACF
user-agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; vivo Y55 Build/MMB29M)
accept-encoding: gzip
===========================================
06-15 09:34:02.251 DEBUG 41911 --- [nio-7016-exec-6] jdbc.core.JdbcTemplate : Executing prepared SQL query
06-15 09:34:02.251 DEBUG 41911 --- [nio-7016-exec-6] jdbc.core.JdbcTemplate : Executing prepared SQL statement [select * from file where id = ?]
然后我继续下载文件,它发送请求并真正下载文件。这是标题。
===========================================
host: 192.168.0.101
remote_addr: 192.168.0.102
x-real-ip: 192.168.0.102
x-forwarded-for: 192.168.0.102
connection: close
cookie: JSESSIONID=DECD58D9A660FBA200BF7F920F9B7ACF
user-agent: AndroidDownloadManager/6.0.1 (Linux; U; Android 6.0.1; vivo Y55 Build/MMB29M)
accept-encoding: identity
===========================================
06-15 09:36:26.231 DEBUG 41911 --- [nio-7016-exec-5] jdbc.core.JdbcTemplate : Executing prepared SQL query
06-15 09:36:26.231 DEBUG 41911 --- [nio-7016-exec-5] jdbc.core.JdbcTemplate : Executing prepared SQL statement [select * from file where id = ?]
在Android chrome或ios safari中不会发生此问题。
我正在使用api服务器的nginx和代理请求,这里是配置和java代码。
nginx的
server {
listen 9900;
server_name localhost;
location / {
root /Users/jiangxingshang/Documents/workspace/WebStorm/gs-logistics-mobile/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location ~ ^/api/ {
proxy_set_header Host $host;
proxy_set_header Remote_Addr $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:7016;
}
}
弹簧控制器
@GetMapping(value = "file/{id}")
void download(@PathVariable String id, String disposition, HttpServletResponse response, HttpServletRequest request) throws IOException {
Enumeration<String> headers = request.getHeaderNames();
System.out.println("===========================================");
while (headers.hasMoreElements()) {
String name = headers.nextElement();
String value = request.getHeader(name);
System.out.println(name + ": " + value);
}
System.out.println("===========================================");
FileObject fileObject = fileObjectService.find(id);
if (fileObject == null) {
response.setStatus(404);
response.getWriter().print("File not found.");
} else {
fileObject.download(disposition, response);
}
}
FileObject javabean
public void download(String disposition, HttpServletResponse response) throws IOException {
if (getDeleted() == 1) {
fileNotFound(response);
return;
}
disposition = StringUtils.defaultIfBlank(disposition, "attachment");
String filePath = AccessTokenFactory.findFactory().buildToken(getPath()).getPath();
FileSystemResource resource = new FileSystemResource(filePath);
if (resource.exists()) {
if ("attachment".equals(disposition)) {
response.setContentType("application/octet-stream");
} else {
response.setContentType(Files.probeContentType(resource.getFile().toPath()));
}
response.setHeader("Content-Length", resource.contentLength() + "");
String name = URLEncoder.encode(getName(),"UTF-8");
response.setHeader("Content-Disposition", String.format("%s;filename=\"%s\"", disposition, name));
try (InputStream is = resource.getInputStream()) {
IOUtils.copy(is, response.getOutputStream());
}
} else {
fileNotFound(response);
}
}