Come posso convertire l'immagine binaria dalla chiamata API all'URI di dati in JavaScript?

StackOverflow https://stackoverflow.com/questions/8394721

  •  28-10-2019
  •  | 
  •  

Domanda

L'API di Google che sto utilizzando sta trasmettendo le immagini solo come dati binari.

Non ho assolutamente idea di come metterlo in un URI di dati per visualizzarlo, grazie per qualsiasi aiuto!

La chiamata di cui sto parlando è Questa chiamata API.

Come puoi vedere, dice:

Il server restituisce byte della foto.

Per la chiamata (è un'estensione), utilizzo i metodi Chrome_EX_OAUTH. Forse ho bisogno di aggiungere qualcosa nell'intestazione per ottenere dati binari reali, non stringa in quanto arriva in questo momento ...

Quello che devo fare è convertire il binario risultante in URI di dati in modo da poterlo visualizzare.


Ok, lo esco dalla richiesta XHR

enter image description here

Ora, non conosco molto le cose binarie. Sono in qualche modo dati binari codificati che presumo? Ho provato a metterlo in BTOA e in altri coder di base64, tutto lancia un errore. Ho provato a sovrascriveremimeType con cose diverse e la "risposta" è cambiata in alcuni modi strani, ma nulla accetta i dati.

Quindi ora ho questo codice:

var nxhr = new XMLHttpRequest();
nxhr.onreadystatechange = function (data) {
    if (nxhr.readyState == 4) {
        console.log(nxhr);
    }
};
nxhr.open(method, url, true);
nxhr.setRequestHeader('GData-Version', '3.0');
nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
nxhr.send('Data to send');

Qualcun altro ha idea di come ottenere questo per me non comprensibile una risposta in un Uri di dati ???

Grazie per qualsiasi aiuto

È stato utile?

Soluzione 2

Ok ho trovato la soluzione ...

Prima di tutto, la richiesta deve sovrascrivere il tipo di retrorazione in X-User definito

xhr.overrideMimeType('text\/plain; charset=x-user-defined');

Successivamente i dati non sono toccati dal browser.

Utilizzare il seguente encoder Base64

Base64 = {

            // private property
            _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

            encodeBinary: function (input) {
                var output = "";
                var bytebuffer;
                var encodedCharIndexes = new Array(4);
                var inx = 0;
                var paddingBytes = 0;

                while (inx < input.length) {
                    // Fill byte buffer array
                    bytebuffer = new Array(3);
                    for (jnx = 0; jnx < bytebuffer.length; jnx++)
                        if (inx < input.length)
                            bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; // throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
                        else
                            bytebuffer[jnx] = 0;

                    // Get each encoded character, 6 bits at a time
                    // index 1: first 6 bits
                    encodedCharIndexes[0] = bytebuffer[0] >> 2;
                    // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
                    encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
                    // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
                    encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
                    // index 3: forth 6 bits (6 least significant bits from input byte 3)
                    encodedCharIndexes[3] = bytebuffer[2] & 0x3f;

                    // Determine whether padding happened, and adjust accordingly
                    paddingBytes = inx - (input.length - 1);
                    switch (paddingBytes) {
                        case 2:
                            // Set last 2 characters to padding char
                            encodedCharIndexes[3] = 64;
                            encodedCharIndexes[2] = 64;
                            break;
                        case 1:
                            // Set last character to padding char
                            encodedCharIndexes[3] = 64;
                            break;
                        default:
                            break; // No padding - proceed
                    }
                    // Now we will grab each appropriate character out of our keystring
                    // based on our index array and append it to the output string
                    for (jnx = 0; jnx < encodedCharIndexes.length; jnx++)
                        output += this._keyStr.charAt(encodedCharIndexes[jnx]);
                }
                return output;
            }
        };

C'è la roba magica pubblicata da Mozilla che non mi ha permesso di codificare correttamente le cose

bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff

Il codice finale sembrerebbe quindi questo ...

oauth.authorize(function () {
    var method = "GET", params = {}, url = photo.href;

    var nxhr = new XMLHttpRequest();
    nxhr.onreadystatechange = function (data) {
        if (nxhr.readyState == 4) {
            console.log("<img src='data:image/*;base64," + Base64.encodeBinary(nxhr.response) + "' />");
        }
    };
    nxhr.open(method, url, true);
    nxhr.setRequestHeader('GData-Version', '3.0');
    nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
    nxhr.overrideMimeType('text\/plain; charset=x-user-defined'); 
});

PS Se si inserisce direttamente "Dati: Image/*" nella finestra del browser, scaricherà il file e non sarà in grado di aprirlo. Ma se lo metti direttamente in un IMG SRC funziona bene!

Altri suggerimenti

Dopo aver condotto alcuni test, ecco la mia risposta:

Per visualizzare semplicemente l'immagine usando il <img> Tag, devi prima codificare il risultato binario con Base64. Puoi farlo in due modi diversi:

  1. Usando JavaScript: Utilizzare una funzione encoder Base64, come questo. Dopo aver codificato i dati binari del risultato, è possibile visualizzare l'immagine utilizzando il <img> tag come così: <img src="data:image/*;base64,[BASE64 ENCODED BINARY]" />. È necessario sostituire [BASE64 ENCODED BINARY] con l'effettivo binario codificato dell'immagine. Suppongo che tu sappia già come modificare gli attributi elementi HTML tramite JavaScript, è abbastanza facile mettere il binario codificato nel src attributo del <img> etichetta.

  2. Usando PHP (la mia preferenza personale): Una volta inviata una richiesta GET all'API, ti restituirà il binario. Usa semplicemente il PHP base64_encode() funzione.

    <img src="data:image/*;base64,<?php echo base64_encode($result); ?>" />

Dove il $result La variabile è ciò che ottieni dalla chiamata API. Puoi usare il Php Curl biblioteca.

Spero che questo aiuti.

Se stai usando un data: Uri, prendo che non ti interessa i browser più vecchi. In tal caso, usa btoa() come suggerito in Come puoi codificare una stringa su Base64 in JavaScript?, e ricadere l'alternativa menzionata nella seconda risposta. Poi il data: Uri è semplice:

data:image/*;base64,<the btoa output>

Tutte le altre soluzioni sono obsolete. Non è necessaria alcuna base64. Guardare la mia risposta su Ottenere dati BLOB dalla richiesta XHR.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top