Pergunta

Eu estou escrevendo um recurso de método de manipulação de onde eu controlar o acesso a vários arquivos, e eu gostaria de ser capaz de fazer uso de cache do navegador.A minha pergunta é dupla:

  1. Quais são as definitiva de cabeçalhos HTTP que eu preciso para verificar a fim de saber com certeza se eu deveria enviar uma resposta 304, e o que eu estou procurando, quando eu faço o check-los?

  2. Além disso, existem alguns cabeçalhos que eu preciso para enviar quando eu, inicialmente, enviar o arquivo (como "Última Modificação') como uma resposta 200?

Alguns psuedo-código seria, provavelmente, o mais útil de resposta.


O que sobre o cabeçalho de controle de cache?Podem os vários valores possíveis que afetam o que você envia para o cliente (nomeadamente max-age) ou deve apenas se-modificado-desde ser obedecido?

Foi útil?

Solução

Aqui está como eu implementado.O código foi trabalhar um pouco mais de um ano e com vários navegadores, então eu acho que é muito confiável.Isto é baseado no RFC 2616 e ao observar o que e quando os diversos navegadores foram envio.

Aqui está o pseudocódigo:

server_etag = gen_etag_for_this_file(myfile)
etag_from_browser = get_header("Etag")

if etag_from_browser does not exist:
    etag_from_browser = get_header("If-None-Match")
if the browser has quoted the etag:
    strip the quotes (e.g. "foo" --> foo)

set server_etag into http header

if etag_from_browser matches server_etag
    send 304 return code to browser

Aqui está um trecho da minha lógica de servidor que lida com isso.

/* the client should set either Etag or If-None-Match */
/* some clients quote the parm, strip quotes if so    */
mketag(etag, &sb);

etagin = apr_table_get(r->headers_in, "Etag");
if (etagin == NULL)
    etagin = apr_table_get(r->headers_in, "If-None-Match");
if (etag != NULL && etag[0] == '"') {
    int sl; 
    sl = strlen(etag);
    memmove(etag, etag+1, sl+1);
    etag[sl-2] = 0;
    logit(2,"etag=:%s:",etag);
}   
... 
apr_table_add(r->headers_out, "ETag", etag);
... 
if (etagin != NULL && strcmp(etagin, etag) == 0) {
    /* if the etag matches, we return a 304 */
    rc = HTTP_NOT_MODIFIED;
}   

Se você quiser alguma ajuda com o etag geração pós-outra pergunta e eu vou achar algum código que faz isso bem.HTH!

Outras dicas

Um 304 Não Modificado resposta pode resultar de uma solicitação GET ou HEAD com um If-Modified-since ("IMS") ou um " Se-Não-Correspondência ("EM") do cabeçalho.

A fim de decidir o que fazer quando você receber esses cabeçalhos, imagine que você está manipulando o pedido GET sem estes cabeçalhos condicionais.Determinar que os valores de sua ETag e data da Última Modificação cabeçalhos seria a resposta e usá-los para tomar a decisão.Espero que você tenha construído o seu sistema de tal forma que determinar isso é menos caro do que construir a resposta completa.

Se há um INM e o valor do cabeçalho é o mesmo valor que teria lugar no ETag, em seguida, responder com 304.

Se há um IMS e o valor da data em que o cabeçalho é mais tarde do que o que você colocaria na data da Última Modificação, em seguida, responder com 304.

Outra coisa, proceda como se o pedido não contiver os cabeçalhos.

Para um mínimo de esforço de abordagem para a parte 2 da sua pergunta, descobrir qual dos (Expira, ETag, e Last-Modified) cabeçalhos você pode facilmente e corretamente produzir em seu aplicativo da Web.

Por sugestão de leitura do material:

http://www.w3.org/Protocols/rfc2616/rfc2616.html

http://www.mnot.net/cache_docs/

Você deve enviar um 304 se o cliente afirmou explicitamente que ele já pode ter a página em cache.Isso é chamado de um GET condicional, que deve incluir o if-modified-since cabeçalho do pedido.

Basicamente, este cabeçalho de solicitação contém uma data a partir da qual o cliente afirma ter uma cópia em cache.Você deve verificar se o conteúdo foi alterado após esta data, e enviar um 304, se ela não.

Ver http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25 para a respectiva secção no RFC.

Estamos também a manipulação de cache, mas segura, de recursos.Se você enviar / gerar um cabeçalho ETAg (que RFC 2616 seção 13.3 recomenda que você DEVE), em seguida, o cliente DEVE usá-lo em uma solicitação condicional (normalmente em um If-None-Match - HTTP_IF_NONE_MATCH - cabeçalho).Se você enviar um cabeçalho Last-Modified (DEVE) e, em seguida, você deve verificar o If-Modified-since - HTTP_IF_MODIFIED_SINCE - cabeçalho.Se você enviar, em seguida, o cliente DEVERÁ enviar, mas ele DEVE enviar o ETag.Observe também que validtion é definido apenas como conferir os cabeçalhos condicionais para a rigorosa igualdade contra o que você gostaria de enviar para fora.Além disso, apenas uma forte avaliador (como um ETag) será usado para variou de pedidos (quando apenas parte de um recurso é solicitado).

Na prática, uma vez que os recursos que estão protegendo são relativamente estáticos, e um segundo tempo de latência é aceitável, nós estamos fazendo o seguinte:

  1. Verifique para ver se o usuário está autorizado a acessar o recurso solicitado

    Se eles não são, Redirecioná-los ou enviar um 4xx resposta, conforme apropriado.Vamos gerar 404 respostas às solicitações que parecem tentativas de hackear ou flagrante tenta executar uma segurança a fim de executar.

  2. Compare o If-Modified-since cabeçalho o cabeçalho Last-Modified, que iria enviar (veja abaixo) para a rigorosa igualdade

    Se elas corresponderem, envie um 304 Não Modificado resposta e sair do processamento da página

  3. Criar um cabeçalho Last-Modified usando o tempo de modificação do recurso solicitado

    Procure o HTTP formato de Data na RFC 2616

  4. Enviar o cabeçalho e o conteúdo do recurso, juntamente com um Tipo de Conteúdo apropriado

Decidimos abster-se de o cabeçalho ETag, pois é um exagero para os nossos propósitos.Suponho que também pode simplesmente usar o carimbo de data / hora como um ETag.Se nos movermos para uma verdadeira ETag do sistema, que, provavelmente, armazenar hashes calculados para os recursos e usá-los como ETags.

Se os recursos são gerados dinamicamente, por exemplo, do conteúdo de banco de dados e, em seguida, ETags pode ser melhor para suas necessidades, pois eles são apenas um texto para ser preenchido como você vê o ajuste.

em relação cache-control:

Você não deveria ter de se preocupar com o controle de cache quando servir, a não ser que a definição é um valor razoável.É basicamente dizendo ao navegador e outro a jusante entidades (como um proxy) o máximo de tempo que deve decorrer antes que o tempo limite da cache.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top