Toon posts:

[JS] headers bestand uitlezen / lastModified

Pagina: 1
Acties:

Verwijderd

Topicstarter
Goedendag,

Wat ik wil bereiken is dat er d.m.v de header van een bestand (in dit geval een afbeelding) wordt bepaald of het bestand opnieuw geladen moet worden (via javascript). De afbeelding wordt door php gegenereerd.

Mijn eerste gedachte was om zelf een header toe te voegen, en die met javascript uit te lezen. Ik kan echter nergens vinden of, en hoe, het mogelijk is om met javascript headers van een bestand uit te lezen. Mijn eerste vraag: is dat uberhaubt mogelijk?

Mijn tweede bedenksel was om document.lastModified te gebruiken, aangezien dit ongeveer op hetzelfde neerkomt. In het php script genereer ik die header dan. In mijn javascript onwetendheid heb ik het volgende geprutst:
JavaScript:
1
2
3
4
5
<script>
test = new Image();
test.src = "http://afbeelding.php?id=1";
document.write( test.lastModified );
</script>

(met op afbeelding.php de juiste URL)

Wat FireFox er echter van maakt is: "undefined"... Is dit ook niet mogelijk, van een ingeladen afbeelding de lastModified uitlezen? Of zie ik iets over het hoofd?

Alvast bedankt,
Roemer

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 23:32

orf

Als je een xmlHTTPrequest doet krijg je de response code. 304 is not modified.

:)

Verwijderd

Topicstarter
euhm.. ik volg je niet helemaal?
Ten eerste, ik gebruik niet xmlHTTPrequest, en daarnaast stop ik "handmatig" de Last-Modified header bij de afbeelding (via php). Dan zou je toch niet "is nog modified" terug moeten krijgen?

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 23:32

orf

Wat ik bedoelde: Als je een statisch bestand (afbeelding) hebt, dan is deze voorzien van een lastModified en eTag header. (dat doet de webserver automatisch).

Doe je vanuit je pagina een xmlHTTPrequest, dan krijg je een statuscode terug. Is dat een 304, dan weet je dat het plaatje niet gewijzigd is. Krijg je een 200 (ok) terug, dan kan een functie aangeroepen worden om de afbeelding in een <img> tag te zetten.

Verwijderd

De enige manier om echt controle hierover te houden is met http headers, niet met de metadata van een bestand :)

Verwijderd

Topicstarter
Verwijderd schreef op woensdag 22 februari 2006 @ 21:40:
De enige manier om echt controle hierover te houden is met http headers, niet met de metadata van een bestand :)
--->
Verwijderd schreef op woensdag 22 februari 2006 @ 21:30:
Wat ik wil bereiken is dat er d.m.v de header van een bestand (in dit geval een afbeelding) wordt bepaald of het bestand opnieuw geladen moet worden (via javascript). De afbeelding wordt door php gegenereerd.
Misschien ben ik hierin onduidelijk geweest, maar ik wil dus juist de headers uitlezen (Gordijnstok) Andere woorden: ik wil een header aan een afbeelding toevoegen, en die met javascript uitlezen. Ik haalde het document.lastModified gedoe erbij, omdat die waarde toch al wordt uitgelezen van het bestand.

Het gebruik van xmlHTTPrequest is hier ook niet wat ik wil bereiken, want dan wordt het bestand al geladen, terwijl ik dat juist zelf wil controleren:

stap 1: client haalt pagina met een afbeelding op, in die afbeelding zit een header
stap 2: client haalt (binnen die pagina, dmv xmlHTTPrequest) een andere pagina/content op, en javascript vergelijkt de content met de (bij stap 1) verkregen header
stap 3: aan de hand van de uitkomst van de vergelijking wordt het de afbeelding opnieuw geladen (of niet), en begint het dus weer vanaf stap 1

Ik hoop dat het nu wat duidelijker is wat ik wil bereiken..

[ Voor 9% gewijzigd door Verwijderd op 22-02-2006 21:48 ]


Verwijderd

Headers beheer je of met een serverside scripting language waar je headers toe kan voegen (no-cache, last-modified) header of via je webserver software.

Verwijderd

Topicstarter
ligt het nou aan mij, of kan jij echt niet lezen?

Het probleem is dus niet het toevoegen van de header, met het UITLEZEN van de header. Het liefst via het uitlezen van een eigen gebruikte header, maar desnoods via lastModified (header: Last-Modified:), omdat die zowiezo (of alleen van het document zelf?) uit te lezen is.

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 23:32

orf

Om met javascript een statuscode (=/ header) uit te lezen, zul je eerst de afbeelding op moeten halen.

Een veel simpelere methode is om een xmlHTTPrequest te doen naar een script; dat script kijkt of de afbeelding gewijzigd is en geeft 0 of 1 als response (enkele bytes). Is het een 1, dan reload je de afbeelding, anders niet...

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Wat Gordijnstok probeert uit te leggen is dat je dergelijke functionaliteit aan de serverkant dient af te vangen; vergelijk
stap 1: client haalt pagina met een afbeelding op, in die afbeelding zit een header
stap 2: client haalt (binnen die pagina, dmv xmlHTTPrequest) een andere pagina/content op, en javascript vergelijkt de content met de (bij stap 1) verkregen header
stap 3: aan de hand van de uitkomst van de vergelijking wordt het de afbeelding opnieuw geladen (of niet), en begint het dus weer vanaf stap 1
met:

stap 1: client doet een request voor een image
stap 2: server kijkt naar de request-headers; zit daar een If-Modified-Since header bij, maar is het plaatje sinds die tijd onveranderd: stuur een 304 Not Modified header terug, stuur anders het plaatje tesamen met een Expires header terug.

hier ben je niet afhankelijk van de client (afgezien van het feit dat dit met javascript praktisch onmogelijk is - XMLHttpRequest biedt nog wel wat mogelijkheden maar dat is ook maar beperkt) en gebruik je gewoon het al bestaande HTTP mechanisme dat hiervoor bedoelt is.

edit: ik zal ook wel stront in m'n ogen hebben, maar ik denk toch dat je zelf veels te moeilijk aan het doen bent en hetgeen je wilt bereiken (wat dat concreet is is mij nog niet duidelijk) veel eenvoudiger kan ;)

[ Voor 24% gewijzigd door crisp op 22-02-2006 22:36 ]

Intentionally left blank


Verwijderd

Headers controleren haalt niet het bestand volledig op. Dus een basic xmlHttpRequest is alles wat je nodig hebt. Vanaf ik dacht IE4, is imgElement.fileModifiedDate aanwezig, voor Gecko zou het even uit moeten proberen. Verder valt er altijd nog wel te controleren dmv een timer. Binnen x milliseconden moet een browser zijn image wel uit de cache geladen hebben. Is het meer, dan kun je een reload doen.

Ik had inderdaad stront in mijn ogen. Kan gebeuren maar opmerkingen als "ligt het nou aan mij, of kan jij echt niet lezen?" kun je denk ik beter voor je houden als je hulp wilt hebben van mensen die hun kostbare tijd aan jouw probleem besteden.

http://www.mschopman.demon.nl/linkchecker.html kijkt ook alleen naar de headers met xmlHttpRequest. Die gaat niet elke pagina compleet inladen. Hij geeft een error, maar dan komt vanwege wazige "cross domain" problemen die niet eens zouden mogen voorkomen.

[ Voor 63% gewijzigd door Verwijderd op 22-02-2006 22:36 ]


Verwijderd

Topicstarter
@Gordijnstok: excuses voor die opmerking, maar misschien is het verstandig om voortaan wat meer uitleg te geven, want het wordt mij pas na het verhaal van crisp duidelijk waar jij op zat te doelen.

Als ik een xmlHTTPrequest doe, wordt het (php) bestand toch wel doorlopen? En het gaat mij juist om het ontzien van het plaatje-genererend-script.

Ik ga maar's kijken of ik dan de manier van crisp kan gebruiken. Bedankt voor de hulp

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Als je gebruik maakt van de juiste headers wordt bij een request (of dat nou een image is of een XMLHttpRequest) altijd de server geraadpleegt. Je kan dus serverside aan de hand van dat request gewoon bepalen of je content terugstuurt of een 304 Not Modified header. In het laatste geval zal de client dus alsnog de gecachede versie gebruiken :)

Intentionally left blank


Verwijderd

Tenzij de client beschikt over een cached versie, met een actieve content expiration en de cache settings op "automatically". Dan wordt de server in zijn geheel niet geraadpleegd, zelfs niet voor een 304 header. Bij "every visit to the page" wordt er in het geval van een actieve content expiration eenmaal het bestand gecontroleerd.

[ Voor 10% gewijzigd door Verwijderd op 22-02-2006 23:23 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Verwijderd schreef op woensdag 22 februari 2006 @ 23:23:
Tenzij de client beschikt over een cached versie, met een actieve content expiration en de cache settings op "automatically". Dan wordt de server in zijn geheel niet geraadpleegd, zelfs niet voor een 304 header. Bij "every visit to the page" wordt er in het geval van een actieve content expiration eenmaal het bestand gecontroleerd.
Je praat nu erg IE ;)

En uit mijn ervaring werkt het volgende gewoon goed in IE (met cache-settings op automatically):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$maxAge = 86400;
$time = time();
$headers = apache_request_headers();

//-- respect request for new version
if (    isset($headers['If-Modified-Since']) &&
    ( !isset($headers['Cache-Control']) || $headers['Cache-Control'] != 'no-cache' ) &&
    ( !isset($headers['Pragma']) || $headers['Pragma'] != 'no-cache' ) )
{
    $orgtime = strtotime($headers['If-Modified-Since']);
    if (filemtime($file) < $orgtime)
    {
        if ($time - $orgtime < $maxAge)
        {
            header('HTTP/1.1 304 Not Modified');
            exit;
        }
    }
}

header('Expires: ' . gmdate('D, d M Y H:i:s', $time + $maxAge) . ' GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $time) . ' GMT');
header('Cache-Control: public, max-age=' . $maxAge);
header('Pragma: !invalid');

@readfile($file);

[ Voor 51% gewijzigd door crisp op 22-02-2006 23:28 ]

Intentionally left blank


Verwijderd

Inderdaad IE. Alles is koek en ei totdat je via javascript elementen gaat aanmaken met images. Bij every visit to the page worden alle images die je aanmaakt opnieuw geladen tenzij je een content expiration header meestuurt. Dan wordt alleen de eerste request op die file uitgevoerd en de rest geladen zonder request voor een lastmodified. Bij automatically wordt voor elke file die je toevoegt een lastmodified header gecontroleerd tenzij je die expiration header meestuurt.

Is bij ons dus sinds we die onderzoeken naar het gedrag in IE hebben uitgevoerd dus ook onderdeel van onze procedures bij het inrichten van IIS, zeker aangezien we redelijk wat dynamisch gegenereerde componenten gebruiken. Het verschil is toch wel bijzonder groot. :)

Voor browsers met een caching systeem wat wel werkt is dit uiteraard niet een issue.

Verwijderd

Topicstarter
@crisp: nogmaals bedankt! Ik denk dat het me met jouw voorbeeld stukjes zeker moet lukken :)

Iets anders, slightly off-topic... Als ik in firefox een xmlhttprequest doe, blijft die pagina maar laden... (het "laad-cirkeltje" blijft bewegen). Klopt dat? Ik doe volgens mij gewoon de standaard dingen die je in elke tutorial tegen komt (al meerdere gecheckt). De pagina die opgevraagd wordt is nu gewoon plain-text.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Welke versie Firefox gebruik je?

Intentionally left blank


Verwijderd

Topicstarter
versie 1.5.0.1
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<script>
function createHTTPHandler()
{
    httphandler = false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope with old IE versions.
    // and security blocked creation of the objects.
    try {
      httphandler = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
       httphandler = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
          httphandler = false;
      }
    }
    @end @*/
    if (!httphandler && typeof XMLHttpRequest!='undefined') {
        httphandler = new XMLHttpRequest();
    }
    return httphandler;
} 

function handelScriptAf() {   
      if (xmlhttp.readyState == 4) // volledig geladen?  
             if (xmlhttp.status == 200) 
             {            
                 document.write(xmlhttp.responseText); 
        } 
        else 
        {       
                  document.write("Er is een probleem opgetreden: "+xmlhttp.statusText);     
          } 
    }
xmlhttp = new createHTTPHandler();
xmlhttp.open("GET", "http://domein/bestand.php",true); 
xmlhttp.setRequestHeader('Eigen-header', 'foobar');
xmlhttp.setRequestHeader("Cache-Control", "no-cache"); 
xmlhttp.onreadystatechange=handelScriptAf;
xmlhttp.send(null)

</script>


Als ik van deze pagina ook de source wil bekijken, krijg ik een blanco pagina?

edit: Als ik de document.write(xmlhttp.responseText) vervang door een alert, stopt hij wel met laden en kan ik ook gewoon de source bekijken... naja.. het werkt iig in globale lijnen, nogmaals, allen bedankt

[ Voor 19% gewijzigd door Verwijderd op 23-02-2006 14:51 ]

Pagina: 1