Ho implementato caricamenti ripristinabili basati su browser nel Cloud Storage di Google utilizzando un XMLHttpRequest inviato a un URL di caricamento ripristinabile creato sul lato server. Funziona perfettamente quando disabilita la sicurezza web, cosa che ho fatto durante lo sviluppo.XMLHttpRequest CORS a Google Cloud Storage funzionante solo nella richiesta di preflight
Ma ora nel mondo reale, CORS continua a creare problemi. Ho provato questo con altri browser (senza successo), ma sono rimasto incollato al chrome per ulteriori test.
Nota: Una voce fake.host
in /etc/HOSTS
viene utilizzata per ingannare chrome in modo da evitare restrizioni localhost. Tuttavia, lo stesso accade con il dominio "reale" del nostro server di test online.
La richiesta viene avviato utilizzando una normale chiamata XMLHttpRequest:
var xhr = this.newXMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('Content-Type', this.currentInputFile.type);
xhr.setRequestHeader('Content-Range', 'bytes ' + startByte + '-' + (this.currentInputFile.size - 1) + '/' + this.currentInputFile.size);
xhr.onload = function(e) {
...
};
...
if (startByte > 0) {
xhr.send(this.currentInputFile.slice(startByte));
} else {
xhr.send(this.currentInputFile);
}
Il browser inizia quindi con successo una richiesta di verifica preliminare:
Remote Address:173.194.71.95:443
Request URL:https://www.googleapis.com/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
Request Method:OPTIONS
Status Code:200 OK
intestazioni di richiesta:
:host:www.googleapis.com
:method:OPTIONS
:path:/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
:scheme:https
:version:HTTP/1.1
accept:*/*
accept-encoding:gzip,deflate
accept-language:en-US,en;q=0.8,de;q=0.6
access-control-request-headers:content-range, content-type
access-control-request-method:PUT
origin:https://fake.host
referer:https://fake.host/upload.xhtml
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
x-client-data:YYYYYY
Parametri stringa di query
uploadType:resumable
name:aa spacetestSMALL_512kb.mp4
upload_id:XXXXXXXXX
risposta intestazioni
access-control-allow-credentials:true
access-control-allow-headers:content-range, content-type
access-control-allow-methods:PUT
access-control-allow-origin:https://fake.host
alternate-protocol:443:quic
content-length:0
content-type:text/html; charset=UTF-8
date:Fri, 05 Sep 2014 14:11:21 GMT
server:UploadServer ("Built on Aug 18 2014 11:58:36 (1408388316)")
status:200 OK
version:HTTP/1.1
... e inizia il PUT-richiesta finché viene trasferito tutti i dati. Ma in seguito Chrome registra silenziosamente un errore senza completare/terminare la richiesta:
XMLHttpRequest non può caricare https://www.googleapis.com/upload/storage/v1/b/my-bucket-name ... XXXXXXXX. Nessuna intestazione 'Access-Control-Allow-Origin' è presente sulla risorsa richiesta. L'origine 'https://fake.host' non è quindi consentita l'accesso.
Questo è ciò che i registri cromati sulla richiesta PUT:
Request URL:https://www.googleapis.com/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
intestazioni di richiesta
Provisional headers are shown
Content-Range:bytes 0-3355302/3355303
Content-Type:video/mp4
Origin:https://fake.host
Referer:https://fake.host/upload.xhtml
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id:YYYYYYY
stringa di query
uploadType:resumable
name:aa spacetestSMALL_512kb.mp4
upload_id:XXXXXXXXX
In particolare, quando si aggiunge lo stesso URL in http://client.cors-api.appspot.com/client e il rilascio qualsiasi richiesta, tutti tranne i tipi di richiesta OPTIONS
falliscono, anche. Sembra che la cloud storage api emetta solo le intestazioni di risposta corrette per le richieste OPTION, ma non le richieste PUT/POST/GET/....
Quindi sto facendo qualcosa di impossibile? C'è qualcosa di rotto? Si tratta di un bug nel cloud storage api? Ho passato ore a googling e a leggere le risposte SO, senza fortuna fino ad ora.
Per ora, potrei verificare periodicamente se il download ha trasferito il 100% dei dati e ignorare semplicemente il risultato della richiesta http, poiché il file viene infatti completamente caricato nel bucket di archiviazione. Ma questa è una brutta soluzione che non voglio davvero usare se il vero problema può essere risolto.
Avete impostato su CORS sul GCS? https://cloud.google.com/storage/docs/cross-origin#Configuring-CORS-on-a-Bucket – Ryan
Sì, certo. Immagino che senza di essa la richiesta di preflight fallirebbe, il che non avviene. Solo la risposta finale dopo aver caricato il file non è valida. – Roben
Puoi mostrare il messaggio che hai usato? Sembra che tu dimentichi il "metodo": ["PUT", "POST", "GET"], – Ryan