提问者:小点点

<不可读>对于POST主体长度为100000字节或以上,也使用blob/FormData


编辑:eis是对的,有一个干扰(Netbean)调试器。

客户端将一些数据发送到Spring Boot servlet:

        fetch("/command", {
            method: 'POST',
            cache: 'no-cache',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify(...)
        });

在服务器端,HttpServletRequest. getReader()返回一个字符串

为了测试,我发送了一个几kB文本字段的内容,而不是JSON字符串。这一次,服务器收到了一个完全相同的字符串,没有任何问题。出于某种原因,只能发送JSON字符串。我测试了限制其大小是否有帮助。事实证明,这是可行的:

body: JSON.stringify(...).substring(0,99999)

但这并没有:

body: JSON.stringify(...).substring(0,100000)

以下内容:

body: new Blob( [ contentsCallback().substring(0, N) ], { type: 'application/json' } )

适用于N

const formData = new FormData();
formData.append('blob', new Blob( [ JSON.stringify(...).substring(0, N) ], { type: 'application/json' } ), 'test');
...
body: formData

适用于N

看起来某个地方有大小限制。我不知道它是在客户端还是服务器端。这是服务器的application.properties的一个片段,我在其中放置了这里讨论的各种属性:

multipart.max-file-size=20MB
multipart.max-request-size=20MB
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=20MB
multipart.maxFileSize=20Mb
multipart.maxRequestSize=20Mb
server.tomcat.max-http-post-size=10000000
server.tomcat.max-http-post-size=100000000
server.tomcat.max-swallow-size=100000000

这是servlet注册的方式:

@Bean
public ServletRegistrationBean commandRegistration() {
    ServletRegistrationBean bean = new ServletRegistrationBean(
            new CommandServlet(), "/command");
    // final int SIZE_LIMIT = 20000000;
    // MultipartConfigElement mc = new MultipartConfigElement(TMP_FOLDER, 
    //         SIZE_LIMIT, SIZE_LIMIT * 2, SIZE_LIMIT / 2);
    // bean.setMultipartConfig(mc);
    return bean;
}

取消注释注释部分不会更改相关限制。

这是fetch()的Chrome数据,它发送完整的150kBJSON(作为接收)

Request URL: https://localhost:8443/?command=save
Request Method: POST
Status Code: 200 
Remote Address: [::1]:8443
Referrer Policy: strict-origin-when-cross-origin
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Content-Type: text/html;charset=UTF-8
Date: Thu, 18 Mar 2021 09:32:00 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,pl;q=0.8,de;q=0.7,fr;q=0.6,ru;q=0.5,es;q=0.4,nl;q=0.3,cs;q=0.2,it;q=0.1,nb;q=0.1
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 146111
Content-Type: application/json
Cookie: JSESSIONID=961B41156DCF6F7C57455AA871525198; JSESSIONID=72CCDD7A91C48660B9DD01041F4BEFBB
Host: localhost:8443
Origin: https://localhost:8443
Pragma: no-cache
Referer: https://localhost:8443/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36
command: save

控制台日志中没有错误或警告。当使用Firefox或我将HTTP服务器从Tomcat切换到Jetty时,限制也存在。

最后,我在所有源和所有jar(包括本地Maven repo中的依赖项)中搜索了

可以增加这个限制吗?如何使用POST方法将大字符串发送到SpringBoot应用程序?这些答案表明POST的实际限制远大于100kB。


共1个答案

匿名用户

评论者怀疑有什么干扰。其中一个提示是调试器,因为gdb使用类似的消息,只是没有以大写字母开头。事实上,该消息(伪装成真正的变量值)是在Netbean/JPDA/JVM调试链中的某个地方产生的。