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 请求做一些事情