Autore Topic: HTML con imgsrc autorizzato su dominio differente  (Letto 1348 volte)

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
HTML con imgsrc autorizzato su dominio differente
« il: 13 Febbraio 2014 ore 14:31 »
Salve gente.

Ho un banalissimo pezzo di codice HTML che gira bene su firefox, ma su chromium non funge.

Mostro in una tabella immagini provenienti da 3 telecamere tramite il programma motion. motion espone immagini JPEG. Il codice non fa altro che ricaricare le immagini ogni secondo.

Il problema è che su chromium per funzionare devo aprire i tre link in un'altra pagina. A tal punto si mette ad andare. Altrimenti non mi mostra nulla.
Firefox invece le mostra al volo  :-\

Ecco il codice ridotto all'osso (una sola immagine):
Codice: [Seleziona]
<html>
  <body>
  <script>
      setInterval(function() {
var myImageElement = document.getElementById('img1');
myImageElement.src = 'http://usr:pwd@xxx.xxx.xxx.xxx:8081?random=' + Math.random();
      }, 1000);
  </script>
  <table border="1">
  <tr>
    <td>    <img width="400" id="img1" src="http://usr:pwd@xxx.xxx.xxx.xxx:8081" >    </td>
  </tr>
  </table>   
  </body>
</html>
Il file sta su un server all'indirizzo ip yyy.yyy.yyy.yyy (a sua volta ad accesso protetto)

Ho pensato a qualche trucchetto per fargli aprire in background le pagine via javascript e autorizzarmi, ma non ho trovato il modo.

Non rognatemi sull'oggetto che non sono riuscito a fare di meglio :)

Offline jmc

  • *
  • Post: 1354
  • Reputazione: 95
    • Mostra profilo
    • The Chakra Project
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #1 il: 14 Febbraio 2014 ore 23:09 »
Io, intanto, ti espongo qualche dubbio:
  • a che serve un accesso protetto se poi username e password sono leggibili in chiaro nel codice della pagina?
  • in che modo viene effettuata l'autenticazione ad yyy.yyy.yyy.yyy? potrebbe essere lì il problema
  • non hai bisogno di recuperare l'elemento img ad ogni esecuzione del codice passato a setInterval, per cui io riformulerei come di seguito:
Codice: [Seleziona]
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>...</title>
        <script type="text/javascript">
            window.addEventListener("load", function () {
                var img = document.getElementById("img1");
                setInterval(function () {
                    img.src = "..." + Math.random();
                }, 1000);
            });
        </script>
    </head>
    <body>
        <img id="img1" src="..." />
    </body>
</html>

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #2 il: 14 Febbraio 2014 ore 23:40 »
Io, intanto, ti espongo qualche dubbio:
  • a che serve un accesso protetto se poi username e password sono leggibili in chiaro nel codice della pagina?
  • in che modo viene effettuata l'autenticazione ad yyy.yyy.yyy.yyy? potrebbe essere lì il problema
  • non hai bisogno di recuperare l'elemento img ad ogni esecuzione del codice passato a setInterval, per cui io riformulerei come di seguito:
ciao jmc, grazie per la risposta!
Allora:
- il sistema è per uso privato, non pubblico. Le password per accedere a motion sul server xxx servono per evitare l'accesso indesiderato alle immagini da parte di terzi direttamente collegandosi a xxx. Chi accede a yyy può tranquillamente conoscere le password di xxx, non è importante.
- l'accesso al server yyy avviene con... il sistema di autenticazione fornito dal provider! Scherzi a parte non so di preciso che tipo di autenticazione sia, ma è implementata dal server (io setto il file html come protetto sull'interfaccia che mi offre register). In ogni caso l'autenticazione a yyy funziona, visto che il file HTML viene caricato bene dal browser.
- l'ultimo punto se ho ben capito è un consiglio di ottimizzazione? in effetti è inutile fargli accedere ogni volta alla struttura (DOM?) del documento per recuperare i riferimenti alle immagini, grazie...

Per capirci la struttura è la seguente:
- sul PC delle telecamere (xxx) ci gira motion. Questo espone le immagini sulle porte 8081-8082-8083 (ecc). Ho protetto l'accesso alle immagini con password.
- disponendo di un sito internet con dominio con servizio di hosting (server yyy) ho voluto caricare il file HTML su questo server. Ovviamente la pagina delle telecamere è protetta da password sia perchè con il sito non centra niente e non voglio che google la indicizzi o ci acceda chiunque, sia perchè sono caxxi miei le immagini delle telecamere  ;D

C'è sicuramente una soluzione migliore, ma al momento questa è quella che preferisco. Anche perchè vorrei evitare di far girare un web server su xxx... (essendo x mio uso personale, anche se funziona solo con Firefox per ora mi può bastare, ma x sfizio avrei voluto mettere a posto  ;))

Offline jmc

  • *
  • Post: 1354
  • Reputazione: 95
    • Mostra profilo
    • The Chakra Project
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #3 il: 15 Febbraio 2014 ore 00:42 »
Ok, quindi la situazione è che i client si collegano ad Y che ospita il web server, e poi richiedono ad X le immagini. Mi dici che aprendo le immagini singolarmente in tab di Chrome si vedono, il che mi farebbe pensare che il tuo setInterval scatti troppo velocemente e cambi src prima che le immagini abbiano terminato il caricamento... però questo cozza col fatto che, a quanto pare, da Firefox vengono visualizzate subito, e correttamente.

Hai provato ad ispezionare il traffico HTTP tramite i developer tools di Chrome? (Ctrl+Shift+I, c'è l'apposita scheda "Network" con cui analizzare il flusso dei dati)

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #4 il: 15 Febbraio 2014 ore 06:27 »
ci ho provato... 2 minuti! purtroppo non ho avuto il tempo di capirci niente. Quando sviluppavo non c'era manco Chrome, quindi l'ambiente non lo conosco bene. cmq ora che mi hai dato la dritta di vedere il traffico HTTP lo faccio.

PS: la cosa strana è che aprendo la/e pagina/e di xxx singolarmente "non visualizza nulla" (penso sia un problema di come chrome vede i dati inviati da motion, non riconosce il formato) ma chiudendo il tab di xxx e riaprendo la pagina in yyy funziona tutto! Riavviando il browser yyy ritorna a far vedere una table vuota.
Per questo punto sul fatto dell'autorizzazione che fallisce su xxx per astrusi motivi

Offline jmc

  • *
  • Post: 1354
  • Reputazione: 95
    • Mostra profilo
    • The Chakra Project
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #5 il: 15 Febbraio 2014 ore 21:42 »
Posso chiederti di vedere i sorgenti? :D

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #6 il: 15 Febbraio 2014 ore 23:09 »
intendi di provare l'accesso?

porta pazienza però, perchè stamattina ho avuto un casino e non ho fatto niente. Vediamo Lunedì se va meglio :)

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #7 il: 15 Febbraio 2014 ore 23:20 »
ho fatto debug in remoto. Quant'è bello lo strumento di debug di chrome!

Sì, non capisco perchè anche se l'url della GET è corretto non riesce ad autenticarsi:

link address:
Codice: [Seleziona]
http://user:pwd@xx.xx.xxx.xxx:8083/?random=0.06620274274609983
request headers:
Codice: [Seleziona]
GET /?random=0.06620274274609983 HTTP/1.1
Host: xx.xx.xxx.xxx:8083
Connection: keep-alive
Accept: image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Referer: http://yyy.yyy.yyy.yyy/privato/telecamere.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
response headers:
Codice: [Seleziona]
HTTP/1.0 401 Authorization Required
Server: Motion/Git-8619d7c17ce112e7196975905c6e840f345141ba
Max-Age: 0
Expires: 0
Cache-Control: no-cache, private
Pragma: no-cache
WWW-Authenticate: Basic realm="Motion Stream Security Access"

Offline jmc

  • *
  • Post: 1354
  • Reputazione: 95
    • Mostra profilo
    • The Chakra Project
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #8 il: 16 Febbraio 2014 ore 01:56 »
Ok, è Motion che richiede autenticazione HTTP per poterti dare l'accesso alla risorsa... credo che l'unica cosa affidabile (cross-browser) sia di caricare le immagini via AJAX e poi applicarle all'elemento <img> in questione.

Il problema è che per caricarle da un altro dominio hai problemi di CORS (Cross-Origin Resource Sharing): il tuo user agent tende a bloccare le richieste che ritiene "illecite", se il server non dimostra di accettare di buon grado la tua richiesta.

Sostanzialmente, dovresti fare in modo che Motion (o chi per lui, eventualmente puoi fare uno script server-side che faccia da tramite tra il client remoto e Motion) risponda con l'header "Access-Control-Allow-Origin: <origine>" - dove "<origine>" è il dominio yyy.yyy.yyy.yyy da cui proviene la richiesta - e con l'header "Access-Control-Allow-Credentials: true" per indicare l'accettazione delle credenziali che gli hai inviato nella richiesta.

Ho caricato sul mio dominio Altervista il seguente script PHP:

Codice: [Seleziona]
<?php

$filename 
"test.jpg";

if (
file_exists($filename)) {
    
header("Content-Disposition: inline");
    
header("Content-Type: image/jpeg");
    
header("Content-Length: " filesize($filename));
    
header("Cache-Control: public");
    if (isset(
$_SERVER["HTTP_ORIGIN"])) {
        
header("Access-Control-Allow-Origin: " $_SERVER["HTTP_ORIGIN"]);
        
header("Access-Control-Allow-Credentials: true");
    }
    
readfile($filename);
}

?>

Come vedi, lo script invia (se necessario) i due header che ti ho indicato, e poi invia i dati dell'immagine. Una pagina di prova che carichi le immagini via AJAX la trovi su questo fiddle: http://jsfiddle.net/danielecocca/43NzP/

Tutto ciò utilizza un po' di cose piuttosto nuove (CORS, XMLHttpRequest2, blobs, Object URLs), che però ormai puoi dare praticamente per scontate sui browser moderni. Tanto ormai si autoaggiornano tutti appena possibile, per cui sei sempre "bleeding edge"... :D

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #9 il: 16 Febbraio 2014 ore 10:00 »
Devo studiarmi bene quanto mi hai scritto! ajax x è è roba nuova (nel senso che ai miei tempi era proprio agli albori)...

Domanda: per aggirare il problema di autenticazione avevo pensato a inserire delle immagini nascoste che linkassero a motion con l'autenticazione (o anche altro modo se esiste, basta far partire una get con autenticazione). Ma temo il problema permanga, giusto? Non ho neanche capito bene perchè chrome non si autentichi. Forse perchè le immagini stanno su un altro dominio rispetto alla pagina HTML?

Per ora mi sembra di aver capito che chrome non comprende la risposta di motion. Vorrebbe che la risposta arrivasse da yyy invece che da xxx.
Spero che sull'hosting che ho il codice PHP ci gira. E' su server linux e penso di sì :)
Praticamente devo fare un redirect da yyy a xxx di modo che Chrome veda un solo dominio, giusto?

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #10 il: 16 Febbraio 2014 ore 10:04 »
Ah, per sfizio ho provato anche Opera.

L'autenticazione funziona, infatti un pezzo delle immagini lo scarica. Ma poi il cretino non ricarica le immagini. Il debugger mi dice che non è stata fatta la richiesta ma scaricata l'immagine dalla cache.

Anche questa cosa sarebbe meglio risolverla dal codice piuttosto che cambiare le impostazioni... ma al momento non ho idea se si possa dire al browser "non cache-are ciò che ti invio"

Offline jmc

  • *
  • Post: 1354
  • Reputazione: 95
    • Mostra profilo
    • The Chakra Project
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #11 il: 16 Febbraio 2014 ore 12:24 »
EDIT: avevo mancato di rispondere alla questione delle immagini nascoste. Sì, direi proprio che presenterebbe lo stesso identico problema. :)

Allora, il problema credo che sia nel fatto che stai cercando di caricare dinamicamente contenuti che hanno come origine un dominio differente: questo è generalmente possibile se le risorse le vuoi "embeddare", ma non se le richiedi dinamicamente via JavaScript (potrebbe essere un accesso illecito alla risorsa, ecco il motivo degli header CORS che abilitino esplicitamente l'accesso per questo o quel dominio). La cosa più semplice, secondo me, sarebbe di non richiedere l'accesso HTTP tramite Motion, ma di richiederlo a monte (su yyy.yyy.yyy.yyy: questo, ovviamente, a patto che xxx.xxx.xxx.xxx non sia pubblicamente raggiungibile, ma mi pare di capire che lo sia...)

Per quanto riguarda la cache, è ovviamente possibile impedire il caching, ma ci vogliono gli header HTTP giusti (e.g., "Cache-Control: max-age=0, no-cache, no-store, private, must-revalidate" ed "Expires: <data di accesso>"), oppure devi simulare la richiesta di una risorsa differente aggiungendo via JavaScript dei parametri sostanzialmente inutili, ma che cambiano da richiesta a richiesta. Quest'ultima scelta è solitamente più semplice perché non richiede interventi sul server: jQuery la fa aggiungendo una stringa del tipo "...&_=<orario>", dove <orario> è Date.now().
« Ultima modifica: 16 Febbraio 2014 ore 12:29 da jmc »

Offline dinolib

  • *
  • Post: 3226
  • Reputazione: 110
    • Mostra profilo
Re:HTML con imgsrc autorizzato su dominio differente
« Risposta #12 il: 16 Febbraio 2014 ore 19:41 »
Per quanto riguarda la cache, è ovviamente possibile impedire il caching, ma ci vogliono gli header HTTP giusti (e.g., "Cache-Control: max-age=0, no-cache, no-store, private, must-revalidate" ed "Expires: <data di accesso>"), oppure devi simulare la richiesta di una risorsa differente aggiungendo via JavaScript dei parametri sostanzialmente inutili, ma che cambiano da richiesta a richiesta. Quest'ultima scelta è solitamente più semplice perché non richiede interventi sul server: jQuery la fa aggiungendo una stringa del tipo "...&_=<orario>", dove <orario> è Date.now().

ed infatti l'avevo fatto con il parametro random. Ma non so perchè opera lo ignora...  :-\

 

Template by Homey | Sito ufficiale | Disclaimer