HTTP2 Nginx 服务器 200 响应 XHR POST 对静态文件的请求
HTTP2 Nginx server 200 response for XHR POST Request to a Static FILE
尝试向 Nginx 服务器上的静态文件发送 POST 请求时 HTTP2 的奇怪行为。立即获得 200 响应,无需在 HTTP2 上发送全部数据并在 HTTP1.1 上上传整个文件没有任何问题。
当我将上传路径更改为“upload.php”时,在 HTTP2 和 1.1 上一切正常。当我们尝试向“upload.bin”发送 POST 请求或在 HTTP2 上“上传”带或不带扩展名的静态文件时出现问题。
<body>
<input type="file" id="file-input" />
<button id="upload-button">Upload File</button>
<div id=live></div>
<div id=live2></div>
<script type="text/javascript">
var live = document.getElementById('live');
var live2 = document.getElementById('live2');
document.querySelector('#upload-button').addEventListener('click', function() {
if(document.querySelector('#file-input').files.length == 0) {
alert('Error : No file selected');
return;
}
let file = document.querySelector('#file-input').files[0];
let allowed_mime_types = [ 'application/zip', 'image/png' ];
let data = new FormData();
data.append('file', document.querySelector('#file-input').files[0]);
let request = new XMLHttpRequest();
request.open('POST', 'upload');
request.upload.addEventListener("progress", progressHandler, function(e) {
});
request.send(data);
function progressHandler(event){
live.innerHTML = "Event.Loaded = " + event.loaded;
var percent = (event.loaded / event.total)*100;
live2.innerHTML = "Progress percent = " + percent;
}
});
处理 post 到 Nginx 配置中的静态文件。
error_page 405 =200 $uri;
为什么 NGINX 对使用 HTTP2 的 POST 请求有这样的表现?
这是故意的。
NGINX 知道您的 405 错误渲染器不需要任何主体,因此对于 HTTP,它会丢弃任何接收到的数据。这确实是 HTTP1.1 的设计方式。
有了HTTP2,它变得更聪明了,它告诉对方中止发送数据,然后发送结果页面。这样做是为了防止将 Internet 数据包浪费在无论如何都会被丢弃的数据上。
HTTP2 和更高版本的工作方式更加智能,并且为已知的事情浪费更少的数据(例如,如果您需要登录以进行文件上传,它只会尽快告诉客户端出现错误,而不是等到您的完整文件上传完毕)
当您向 .php 文件发送请求时,php 进程会接管它,它无法立即 return 结果,所以NGINX 在显示错误之前将整个页面流式传输到 php,因为 PHP 只有在收到文件后才开始执行页面上的代码,并且它可能会对 POST 请求做一些事情
尝试向 Nginx 服务器上的静态文件发送 POST 请求时 HTTP2 的奇怪行为。立即获得 200 响应,无需在 HTTP2 上发送全部数据并在 HTTP1.1 上上传整个文件没有任何问题。
当我将上传路径更改为“upload.php”时,在 HTTP2 和 1.1 上一切正常。当我们尝试向“upload.bin”发送 POST 请求或在 HTTP2 上“上传”带或不带扩展名的静态文件时出现问题。
<body>
<input type="file" id="file-input" />
<button id="upload-button">Upload File</button>
<div id=live></div>
<div id=live2></div>
<script type="text/javascript">
var live = document.getElementById('live');
var live2 = document.getElementById('live2');
document.querySelector('#upload-button').addEventListener('click', function() {
if(document.querySelector('#file-input').files.length == 0) {
alert('Error : No file selected');
return;
}
let file = document.querySelector('#file-input').files[0];
let allowed_mime_types = [ 'application/zip', 'image/png' ];
let data = new FormData();
data.append('file', document.querySelector('#file-input').files[0]);
let request = new XMLHttpRequest();
request.open('POST', 'upload');
request.upload.addEventListener("progress", progressHandler, function(e) {
});
request.send(data);
function progressHandler(event){
live.innerHTML = "Event.Loaded = " + event.loaded;
var percent = (event.loaded / event.total)*100;
live2.innerHTML = "Progress percent = " + percent;
}
});
处理 post 到 Nginx 配置中的静态文件。
error_page 405 =200 $uri;
为什么 NGINX 对使用 HTTP2 的 POST 请求有这样的表现?
这是故意的。
NGINX 知道您的 405 错误渲染器不需要任何主体,因此对于 HTTP,它会丢弃任何接收到的数据。这确实是 HTTP1.1 的设计方式。
有了HTTP2,它变得更聪明了,它告诉对方中止发送数据,然后发送结果页面。这样做是为了防止将 Internet 数据包浪费在无论如何都会被丢弃的数据上。
HTTP2 和更高版本的工作方式更加智能,并且为已知的事情浪费更少的数据(例如,如果您需要登录以进行文件上传,它只会尽快告诉客户端出现错误,而不是等到您的完整文件上传完毕)
当您向 .php 文件发送请求时,php 进程会接管它,它无法立即 return 结果,所以NGINX 在显示错误之前将整个页面流式传输到 php,因为 PHP 只有在收到文件后才开始执行页面上的代码,并且它可能会对 POST 请求做一些事情