當前位置:
首頁 > 知識 > Web服務中上傳文件大小的限制

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文件忽略不必要上傳的文件