origin missing headers control allow php http-headers xmlhttprequest cors symfony

php - missing - Seguimiento de progreso de XMLHttpRequest y Symfony(CORS)



no access control allow origin javascript (1)

Entonces, el problema era que el mod_deflate de Apache estaba comprimiendo la respuesta en GZIP, lo que hacía que la longitud no fuera del lado del cliente computable (porque Apache corta la respuesta a partir de lo que he leído).

La solución rápida y sucia es deshabilitar la compresión de esa URL en su configuración de Apache. Si no puede, o no quiere hacerlo para mantenerlo optimizado, hay una solución más elaborada tomada de aquí

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

entonces su función de progreso debería verse más o menos así:

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; };

No estoy seguro si funcionará tan bien, sin embargo, depende si e.loaded se basa en la respuesta comprimida o descomprimida, pero hay otras posibles pistas para usted en esa página

También puedes probar esto, tomado de aquí , te dejaré traducirlo a Symfony porque no estoy seguro de cómo estás configurando tu contenido, pero básicamente se trata de descomprimir los datos tú mismo de antemano para que Apache no lo haga.

// 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

Así que más o menos agregue los dos primeros if en su controlador, o donde sea que establezca el contenido de la Respuesta y mantenga su Escucha de Evento tal como está.

Esas son las dos soluciones menos "hacky" que pude encontrar. Además de eso, su suposición es tan buena como la mía, no la he probado antes.

Estoy creando un sitio web usando el framework Symfony, en un servidor OVH. Cuando un usuario cambia de página, creo una nueva XMLHttpRequest para evitar volver a cargar toda la página y mejorar la experiencia del usuario.

Todo funciona bien, pero quiero agregar una barra de carga mientras la página siguiente se carga de forma asincrónica. Lamentablemente, el parámetro lengthComputable era falso. Para resolver este problema, configuré el encabezado en Symfony3 justo antes de enviar la respuesta con estas líneas:

$length = strlen($event->getResponse()->getContent()); $event->getResponse()->headers->set(''Content-Length'', $length); $event->getResponse()->headers->set(''Accept-Ranges'', "bytes"); $event->getResponse()->sendHeaders();

Este truco funciona en mi servidor de desarrollo local, lengthComputable se establece en verdadero y puedo calcular el porcentaje de carga actual. Pero cuando pongo todo en mi servidor de desarrollo remoto, lengthComputable es falso nuevamente.

Aquí está el encabezado de respuesta usando estas cuatro líneas:

Accept-Ranges:bytes Accept-Ranges:bytes Cache-Control:no-cache Cache-Control:no-cache Content-Encoding:gzip Content-Length:3100 Content-Length:3100 Content-Type:text/html; charset=UTF-8 Date:Sat, 28 Jan 2017 12:34:08 GMT Server:Apache Set-Cookie:PHPSESSID=***; path=/; HttpOnly Vary:Accept-Encoding

(Y sí, algunos parámetros están presentes dos veces)

Creo que esto está relacionado con la política de encabezado de origen cruzado, pero no puedo encontrar una solución.

Intenté establecer otros parámetros como

$responseHeaders->set(''Access-Control-Allow-Headers'', ''content-type'');

e incluso

$responseHeaders->set(''Access-Control-Allow-Origin'', ''*'');

Seguí e intenté estos enlaces

Symfony2. No puedo configurar el encabezado Content-Length

¿Cómo puedo acceder al encabezado Content-Length desde una solicitud Ajax de dominio cruzado?

CORS con encabezados php

EDITAR

No estoy utilizando ningún proxy, y mi servidor está alojado en OVH.

Aquí está mi código de JavaScript (nada excepcional)

ajax_oReq = new XMLHttpRequest(); ajax_oReq.addEventListener("progress", progress, false); ajax_oReq.addEventListener("load", complete, false); ajax_oReq.addEventListener("error", error, false); ajax_oReq.addEventListener("abort", error, false); params = "ajax=1"; if(url.indexOf(''?'')!=-1){ params = "&"+params; }else{ params = "?"+params; } ajax_oReq.open("GET", url+params, true); ajax_oReq.send();

En mi función progress(evt) , puedo ver que lengthComputable es falso registrando el parámetro evt .

En mi función complete(evt) , puse evt.target.response en mi div correspondiente.

Solo quiero agregar que cuando uso este código, recibo el último evento de progreso después de aproximadamente 500 ms con una longitud cargada igual a la longitud total de la página (por lo que el 100% del documento, pero la lengthComputable es falsa y el total es igual a 0 así que lo sé solo porque miro mis encabezados cuando la carga está terminando) Pero se necesitan aproximadamente 5 segundos más para que se llame a la función complete . Creo que esto se debe a que la longitud del contenido no se conoce. De todos modos, cuando elimino mis 4 líneas de código (las primeras), este problema desaparece pero siempre no tengo lengthComputable=true ...

Gracias por tu tiempo !