问题描述
我已切换到 http/2 和 apache,但上传进度不再起作用。
我在控制台中跟踪 event.loaded 并且在实际上传未完成时达到 100% 太快,有时它刚刚开始。
当我切换回 HTTP/1.1 时,一切正常,功能相同。
我一整天都在搜索这个问题,发现了一些有趣的帖子,其他用户报告说 anivirus 有问题。在我的电脑上,我有 Eset Internet Security,当我禁用 HTTPS 扫描时,xhr 进度工作正常。但是当我启用防病毒但禁用 http2 时,网站上传进度工作正常。所以只有启用了 http2 和防病毒软件,我才会遇到这个问题。 有什么解决办法吗? 这是示例和代码的一部分,应该支持上传进度。
function uploadFile_() {
var filedata = new FormData();
filedata.append("file1",file);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress",progressHandler,function(e) {
if (prevLoaded !== 0 && e.loaded <= prevLoaded) {
xhr.abort();
return;
}
prevLoaded = e.loaded;
},false);
xhr.addEventListener("load",completeHandler,false);
xhr.addEventListener("error",errorHandler,false);
xhr.addEventListener("abort",abortHandler,false);
xhr.open("POST",'https://example.com/upload-api/video',true);
xhr.withCredentials = true;
xhr.send(filedata);
}
function progressHandler(event) {
var percent = (event.loaded / event.total)*100;
console.log(percent);
}
解决方法
这是我做的
添加了一个新的位置来处理上传
location = /upload {
proxy_pass http://localhost:80/upload.bin;
}
现在使用 http2 发布请求,文件正在上传,也可以在 http1.1 上运行
@Ferrybig 回答我的问题
这是故意的。
NGINX 知道您的 405 错误渲染器不需要任何正文,因此使用 HTTP,它会丢弃任何接收到的数据。这就是 HTTP1.1 的真正设计方式。
使用 HTTP2,它变得更聪明,它告诉对方中止发送数据,并发送结果页面。这样做是为了防止将互联网数据包浪费在无论如何都会被丢弃的数据上。
HTTP2 及更高版本的工作方式更智能,并且为已知事物浪费更少的数据(例如,如果您需要登录以上传文件,它只会尽快告诉客户端有是一个错误,而是等到您的完整文件上传完毕)
当你向 .php 文件发送请求时,php 进程接管了它,它没有办法立即返回结果,所以 NGINX 在显示错误之前将整个页面流式传输到 php,因为 PHP仅在收到文件后才开始执行页面上的代码,并且它可能会对 POST 请求执行某些操作