XMLHttpRequest progress tracking and Symfony (CORS)

为君一笑 提交于 2019-12-06 08:47:20
Tom Toms

So the problem was that Apache's mod_deflate was compressing the response in GZIP, resulting in the length not being computable client side (because Apache chunks the response from what I've read).

The quick & dirty solution is to disable compression for that URL in your Apache settings. If you cannot, or do not want to in order to keep it optimized, there is a more elaborate solution taken from here

$event->getResponse()->headers->set('x-decompressed-content-length', $length);

then your progress function should look something like:

var progress = function (e) {
      var contentLength;
      if (e.lengthComputable) {
        contentLength = e.total;
      } else {
        contentLength = e.target.getResponseHeader('x-decompressed-content-length');
      }
      var progress = (e.loaded / contentLength) * 100;
    };

I'm not sure it will work that well tho, it depends if e.loaded is based on the compressed or decompressed response, but there are other possible leads for you on that page

You could also try this, taken from here, i will let you translate it to Symfony because I'm not sure of how you are setting your content but basically it is about gzipping the data yourself beforehand so that Apache does not do it.

    // checks if gzip is supported by client
    $pack = true;
    if(empty($_SERVER["HTTP_ACCEPT_ENCODING"]) || strpos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') === false) //replace $_SERVER part with SF method
    {
        $pack = false;
    }

    // if supported, gzips data
    if($pack) {
        $replyBody = gzencode($replyBody, 9, FORCE_GZIP); // Watch out 9 is strong compression
        // Set SF's Response content with gzipped content here
        header("Content-Encoding: gzip"); // replace that with appropriate SF method
    } else {
        // Set SF's Response content with uncompressed content here
    }

    // compressed or not, sets the Content-Length           
    header("Content-Length: " . strlen($replyBody)); // replace that with appropriate SF methods

So pretty much add the first two if in your controller, or wherever you set the Response's content and keep your Event Listener as is.

Those are the two the least "hacky" solutions I could find. Further than that, your guess is as good as mine, I haven't tried it before.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!