Javascript Angular 8无法从请求中读取响应,如果请求中有一个大blob

Javascript Angular 8无法从请求中读取响应,如果请求中有一个大blob,javascript,angular,nginx,flask,Javascript,Angular,Nginx,Flask,我正在开发一个API,它有一个端点来用一个大blob(15MB左右)更新表,这个API更新表,然后用JSON响应 当该端点接收到一个小blob(几个字节)时,angular可以读取JSON并向用户显示结果。如果此端点接收到一个大blob,则整个请求似乎会失败,如firefox在控制台中所示: 我不认为这是一个CORS问题,因为我向这个服务器发出的所有其他请求都是可以的,即使这个请求在blob足够小的情况下也是可以的 我是usgin Angular 8、Python 3(带Flask)和Mysq

我正在开发一个API,它有一个端点来用一个大blob(15MB左右)更新表,这个API更新表,然后用JSON响应

当该端点接收到一个小blob(几个字节)时,angular可以读取JSON并向用户显示结果。如果此端点接收到一个大blob,则整个请求似乎会失败,如firefox在控制台中所示:

我不认为这是一个CORS问题,因为我向这个服务器发出的所有其他请求都是可以的,即使这个请求在blob足够小的情况下也是可以的

我是usgin Angular 8、Python 3(带Flask)和Mysql,但我不认为数据库或服务器端配置有问题(例如,对于Mysql,max_allowed_数据包或innodb_log_file_size,对于nginx,客户端_max_body_size),因为服务器在插入端点中接收完全相同的文件,一切正常。 如果我保存了一个15MB的文件,它是成功的,但是如果我尝试用另一个大小完全相同的文件更新该文件,则会出现错误

另一件让我相信问题不在服务器端的事情是,nginx访问日志只显示成功的请求(所有请求都以代码200响应)

所以我认为问题只能是角度上的,但是如果水滴很小的话,问题就可以解决了,我完全不知道问题在哪里

以下是发出请求的服务:(insert适用于所有大小的blob,仅适用于小blob)

我还有一个拦截器:

export class ApiInterceptor implements HttpInterceptor {
    constructor(private toastr: ToastrService, private progress: ShowProgressService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        let newHeaders = { 'Authorization': localStorage.getItem('jwt') || ""}
        const cloneReq = req.clone({
            setHeaders: newHeaders
        });


        return next.handle(cloneReq).pipe(
            tap((event: any)=>{
                if(event.body && event.body.msg && event.body.error!=undefined){
                    if(event.body.error){
                        this.toastr.error(event.body.msg)
                    } else{
                        this.toastr.success(event.body.msg)
                    }
                }

                // shows upload progress
                if(event.type === HttpEventType.UploadProgress){
                    let percentDone = Math.round((100 * event.loaded) / event.total);
                    this.progress.showUpload(percentDone)

                }

                if(event.type === HttpEventType.DownloadProgress){
                    let percentDone = Math.round((100 * event.loaded) / event.total);
                    this.progress.showDownload(percentDone)
                }

            })
        );
    }
}
答复:

HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Thu, 13 Feb 2020 20:30:39 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: GET, HEAD, PUT, OPTIONS, DELETE
Access-Control-Allow-Origin: http://url
Vary: Origin
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT

根据您添加的选项响应,您似乎没有正确设置服务器对CORS选项请求的响应中的
访问控制允许来源


尝试设置
Access Control Allow Origin:
在服务器的响应中查看CORS是否是问题所在,然后将
*
通配符替换为您将使用的适当的源代码,以防止潜在的恶意跨源请求

我可以在您的DocumentService中看到您正在发布
这很好,但是
PUT
调用失败。CORS选项响应中列出了哪些标题?可能是PUT和大小的组合导致您的请求以不受支持的请求类型(多部分、二进制等)发送,而较小的数据按预期发送。只需使用选项请求编辑问题。如果是这种情况,NGINX会在服务器中列出一个错误,或者与200不同的东西,不是吗?看起来您的访问控制允许源代码没有返回兼容的源代码字符串。我看到标题上写着
http://url
这看起来像是字符串插值错误。在某些背景下,CORS完全由浏览器强制执行。浏览器阻止您查看响应数据并抛出错误。NGINX不会以错误响应,并且很可能仍然会以适当的数据响应,如果源站与访问控制允许源站不匹配,浏览器将对其进行编辑。
export class ApiInterceptor implements HttpInterceptor {
    constructor(private toastr: ToastrService, private progress: ShowProgressService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        let newHeaders = { 'Authorization': localStorage.getItem('jwt') || ""}
        const cloneReq = req.clone({
            setHeaders: newHeaders
        });


        return next.handle(cloneReq).pipe(
            tap((event: any)=>{
                if(event.body && event.body.msg && event.body.error!=undefined){
                    if(event.body.error){
                        this.toastr.error(event.body.msg)
                    } else{
                        this.toastr.success(event.body.msg)
                    }
                }

                // shows upload progress
                if(event.type === HttpEventType.UploadProgress){
                    let percentDone = Math.round((100 * event.loaded) / event.total);
                    this.progress.showUpload(percentDone)

                }

                if(event.type === HttpEventType.DownloadProgress){
                    let percentDone = Math.round((100 * event.loaded) / event.total);
                    this.progress.showDownload(percentDone)
                }

            })
        );
    }
}
Host: url
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: */*
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: authorization
Referer: http://url/dashboard
Origin: http://url
DNT: 1
Connection: keep-alive
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Thu, 13 Feb 2020 20:30:39 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: GET, HEAD, PUT, OPTIONS, DELETE
Access-Control-Allow-Origin: http://url
Vary: Origin
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT