Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

265
Views
jQuery: acceda a la respuesta AJAX binaria dentro de la función completa o acceda al objeto XHR fuera de las funciones de devolución de llamada?

Hay muchas preguntas sobre el manejo de respuestas AJAX binarias con jQuery como this , this y this . Ninguna ayuda.

Objetivos: (1) determinar dinámicamente si una respuesta contiene datos binarios y manejarlos de manera diferente al texto; (2) analizar encabezados de respuesta; y (3) hacer ambas cosas desde una sola función.

Idealmente, esto se puede hacer desde la función complete , pero la función complete no tiene acceso al objeto XHR. Se supone que jqXHR es un superconjunto del objeto XHR, pero XHR.response está en blanco.

El valor de retorno de $.ajax(settings) contiene los datos binarios, pero el objeto XHR ya no está disponible, por lo que parece que no es posible analizar los encabezados de respuesta.

¿Es posible acceder a la respuesta AJAX binaria dentro de la devolución de llamada completa o acceder al objeto XHR fuera de las funciones de devolución de llamada? los

 // Assume @data contains body and URL values. let settings = { url: data.url, method: "post", timeout: 0, contentType: false, processData: false, data: data.body, xhr: function() { // Create XMLHttpRequest object. let xhr = new XMLHttpRequest(); // Handle event for when response headers arrive. xhr.onreadystatechange = function() { if (xhr.readyState == 2) { if (xhr.status == 200) { xhr.responseType = 'blob'; } else { xhr.responseType = 'text'; } } }; return xhr; }, complete: function(xhr, status, error) { // Can access response headers but not binary response here. } }; let response = await $.ajax(settings); // @response is blob but cannot access XHR object here.
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Supongo que estás usando jQuery v1.5+. La devolución de llamada complete quedó obsoleta en favor de always , que incluye el cuerpo de la respuesta. Podría obtenerlo, junto con los encabezados de respuesta, en una sola función haciendo algo como:

 $.ajax({ url: 'https://static.wikia.nocookie.net/5dabc4c4-7cdb-438d-ba57-6b09afffcbb4', method: 'get', }) .always((responseBody, responseStatus, xhr) => { // You don't need this check when using .done() if (responseStatus === 'success') { if (xhr.getResponseHeader('content-type').startsWith('image')) { processImage(responseBody) } } })

Esto también debería funcionar en tu ejemplo. Déjame saber si eso funcionó.

over 4 years ago · Santiago Trujillo Report

0

No sé si está limitado por alguna versión arcaica de jQuery, pero en realidad puede hacer todo eso.

El valor de retorno de $.ajax(settings) contiene los datos binarios, pero el objeto XHR ya no está disponible, por lo que parece que no es posible analizar los encabezados de respuesta.

Técnicamente , no. El valor de retorno de $.ajax(settings) es el objeto jqXHR, por lo que puede acceder al mismo objeto que obtiene dentro de las devoluciones de llamada. En su código, está utilizando el patrón async/await y, por lo tanto, no puede acceder al objeto jqXHR. pero puedes hacerlo

 let jqXHR = $.ajax(settings); jqXHR.then((response) => { console.log(response); console.log(res.getAllResponseHeaders()); });

De esta forma, obtendrá tanto el objeto jqXHR como el objeto de respuesta.

Idealmente, esto se puede hacer desde la función completa, pero la función completa no tiene acceso al objeto XHR. Se supone que jqXHR es un superconjunto del objeto XHR, pero XHR.response está en blanco.

Porque estás accediendo a él en el momento equivocado. Para que se complete la propiedad de response , debe esperar hasta readyState 4 en lugar de 2 . Consulte XHR readyState .
Por otra parte, también puede obtener el objeto de respuesta dentro de la devolución de llamada completa. Simplemente trate el parámetro de devolución de llamada xhr de la misma manera que lo haría con la respuesta $.ajax(settings) .

 complete: function(xhr, status, error) { res.then((response) => { console.log(response); console.log(res.getAllResponseHeaders()); }); }

Si está utilizando las versiones más nuevas de jQuery (supongo que las últimas 2-3 años), incluso puede escribir este código ordenado

 complete: async function (xhr, status, error) { console.log(xhr.getAllResponseHeaders()); console.log(await xhr); }

Y si literalmente necesitas el objeto XHR, también puedes hacer este truco.

 let xhr; let settings = { //rest of things xhr: function () { return xhr = new XMLHttpRequest(); } }; let jqXHR = $.ajax(settings); xhr.onreadystatechange = function() { if (xhr.readyState == 2) { if (xhr.status == 200) { xhr.responseType = 'blob'; } else { xhr.responseType = 'text'; } } }; let response = await jqXHR; console.log(response);
over 4 years ago · Santiago Trujillo Report

0

Para determinar dinámicamente la respuesta, es más conveniente usar la función de success en lugar de always o complete (estas también se ejecutarán en caso de error). En él, obtiene el objeto jqXHR y puede leer el tipo de datos que se devolvió. Después de determinar que es binario (en el código a continuación, es image/png ), puede convertir la respuesta de texto a binario y, opcionalmente, colocarlo en un Blob . Al igual que:

 let data = { url: "https://www.gravatar.com/avatar/cc0c5253923613abd592330ed8adb3a0?s=48&d=identicon&r=PG", body: {} } let settings = { url: data.url, method: "post", timeout: 0, contentType: false, processData: false, data: data.body, success: function(response, status, jqXHR) { var type = jqXHR.getResponseHeader('content-type'); console.log(response); console.log(type); if(type === 'image/png'){ var output = []; for (var i = 0; i < response.length; i++) { output.push( response[i].charCodeAt(0).toString(2) + " "); } output = new Blob(output, {type : type}); console.log(output); } else{ console.log('type is not image/png'); } }, error: function(jqXHR, textStatus, errorThrown) { console.log("an error was encountered", errorThrown); } }; $.ajax(settings);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!