Web服務中上傳文件大小的限制
為了減輕伺服器負荷,避免DDoS攻擊,必須限制客戶端的文件上傳大小。
常用兆和位元組對應表:
引用
1 MB = 1048576 B
2 MB = 2097152 B
5 MB = 5242880 B
10 MB = 10485760 B
20 MB = 20971520 B
50 MB = 52428800 B
100 MB = 104857600 B
200 MB = 209715200 B
一般請求的處理流是:客戶端 -> Web伺服器 -> Web容器 -> 框架。
所以在任何一個環節都可以對文件大小進行限制。
(1)客戶端限制
常用的開源文件上傳組件都可以限制文件大小。
jQuery-File-Upload:maxFileSize
plupload:max_file_size
Dropzone:maxFilesize
FineUploader:sizeLimit
(2)Web伺服器限制
Nginx:client_max_body_size(ngnix.conf)
默認是1MB,超過後直接返回413 (Request Entity Too Large) 。設置為0時表示無限制。
server {
client_max_body_size 1m;
location /users/profile/edit/avatar {
client_max_body_size 2m;
}
location /users/profile/edit/images {
client_max_body_size 5m;
}
}
Apache:LimitRequestBody(.htaccess)
默認為0(無限制),可以指定0到2GB的數值。
<VirtualHost *:8000>
<Location />
LimitRequestBody 1048576
</Location>
<Location /users/profile/edit/avatar>
LimitRequestBody 2097152
</Location>
<Location /users/profile/edit/images>
LimitRequestBody 5242880
</Location>
</VirtualHost>
(3)Web容器限制
Tomcat連接器:maxPostSize(server.xml)
默認是2MB。設置為0時表示無限制。
<Connector port="8009"
protocol="AJP/1.3"
redirectPort="8443"
maxPostSize="10485760" /> <-10MB
<Connector port="8080"
protocol="HTTP/1.1"
redirectPort="8443"
maxPostSize="10485760"/> <-10MB
Servlet 3.0:multipart-config(web.xml)
<multipart-config>
<location>/tmp</location>
<max-file-size>5242880</max-file-size>
<max-request-size>10485760</max-request-size>
<file-size-threshold>32768</file-size-threshold>
</multipart-config>
或Servlet類註解:
@MultipartConfig(
location="/tmp",
maxFileSize=5242880,
maxRequestSize=10485760,
fileSizeThreshold=32768
)
(4)框架限制
SpringBoot設置:
#application.properties
spring.http.multipart.max-file-size=5MB
spring.http.multipart.max-request-size=10MB
Java配置
@Bean
public MultipartConfigElement multipartConfigElement {
MultipartConfigFactory factory = new MultipartConfigFactory;
factory.setMaxFileSize("5MB");
factory.setMaxRequestSize("10MB");
return factory.createMultipartConfig;
}
默認採用StandardServletMultipartResolver ,所以上邊的定義和Servlet 3.0的定義是一致的。也可以採用CommonsMultipartResolver。
Apache Commons Upload設置:
@Bean
public CommonsMultipartResolver multipartResolver {
CommonsMultipartResolver cmr = new CommonsMultipartResolver;
cmr.setMaxUploadSize(10485760);
cmr.setMaxUploadSizePerFile(5242880);
return cmr;
}
文件大小限制後,超大文件如何上傳?
Spring MVC大文件的斷點續傳這篇文章說的是如何下載大文件,和如何上傳大文件很類似,把大文件分割成小的chunks逐個上傳。需要的是瀏覽器端和伺服器端都支持才行。
瀏覽器
如果瀏覽器自身支持的話,大多數開源組件都能做分割上傳,
$(function {
$("#upload").fileupload({
url: "http://localhost:8080/upload",
type: "POST",
dataType: "json",
singleFileUploads: true,
autoUpload: true
});
$("#uploadChunked").fileupload({
url: "http://localhost:8080/upload",
type: "POST",
dataType: "json",
singleFileUploads: true,
autoUpload: true,
maxChunkSize: 1048576
});
});
伺服器
接收文件數據時就需要特殊處理一下。
- 根據HTTP頭部是否有Content-Range參數分成兩個不同方法
- 如果是Chunk上傳的話,第一次為創建文件,之後皆是往文件中追加內容
@RestController
public class UploadController {
private static final String FILE_DIR = "d:";
private static final Pattern RANGE_PATTERN = Pattern.compile("bytes ([0-9]+)-([0-9]+)/([0-9]+)");
@PostMapping(value = "/upload", headers = "!Content-Range")
public Map<String, String> uploadMultipart(@RequestParam("file") final MultipartFile file, HttpServletResponse res) throws Exception {
String fileName = file.getOriginalFilename;
File source = new File(FILE_DIR + fileName);
file.transferTo(source);
Map<String, String> result = new HashMap<String, String>;
result.put("name", FILE_DIR + fileName);
return result;
}
@PostMapping(value = "/upload", headers = "Content-Range")
public Map<String, String> uploadChunked(HttpServletRequest req, HttpServletResponse res) throws Exception {
String contentRange = req.getHeader("Content-Range");
String begin = "";
Matcher matcher2 = RANGE_PATTERN.matcher(contentRange);
if (matcher2.matches) {
begin = matcher2.group(1);
}
MultipartHttpServletRequest multiReq = (MultipartHttpServletRequest) req;
MultipartFile f = multiReq.getFile("file");
String fileName = f.getOriginalFilename;
if ("0".equals(begin)) {
File source = new File(FILE_DIR + fileName);
f.transferTo(source);
} else {
Path file = Paths.get(FILE_DIR, fileName);
Files.write(file, f.getBytes, StandardOpenOption.APPEND);
}
Map<String, String> result = new HashMap<String, String>;
result.put("name", FILE_DIR + fileName);
return result;
}
}


※大數據「二」HDFS部署及文件讀寫
※C多線程之旅(7)——終止線程
※withCredentials 屬性
※基於jQuery開發的手風琴插件 jquery.accordion.js
TAG:科技優家 |
※JSP 文件上傳
※SpringMVC國際化與文件上傳
※linux利用scp遠程上傳下載文件/文件夾
※美國初創公司Nectome推出「意識上傳」服務
※PHP之ThinkPHP框架(驗證碼、文件上傳、圖片處理)
※Hadoop如何將TB級大文件的上傳性能優化上百倍?
※Mozilla VR Hub現在可以共享Web剪貼板和上傳的內容
※「SpringMVC」上傳並顯示圖片
※Spring Boot 文件上傳
※詳細全面的 SpringBoot 文件上傳
※谷歌Facebook等推新數據轉移標準 無需下載和上傳
※SpringBoot | 第十七章:web 應用開發之文件上傳
※Mozilla VR Hub現在可以共享Web剪貼板和上傳的內容
※如何繞過並利用Bucket的上傳策略和URL簽名
※初創公司Nectome推出一種「百分之百致命」的意識上傳服務
※Web安全之Openfire的插件腳本上傳漏洞復現
※GitHub撤下被泄露的Snapchat源碼 黑客揚言重新上傳
※「Hadoop」hadoop 文件上傳和下載分析
※eBay賣家Facebook營銷指南:在Facebook頁面上上傳什麼?
※Github使用.gitignore文件忽略不必要上傳的文件