关于Apache的内容协商(2)

Apache可以协商的内容基本有四类:

  1. 文档类型: content-type, 通过accept来说明
  2. 语言: language, 通过accept-language来说明
  3. 字符集: charset, 通过accept-charset来说明
  4. 编码: encoding, 通过accept-encoding来说明; (注意是传输过程的编码,不是字符的编码)

相关源码参考:
modules/mappers/mod_negotiation.c

  1. typedef struct {
  2.     apr_pool_t *pool;
  3.     request_rec *r;
  4.     neg_dir_config *conf;
  5.     char *dir_name;
  6.     int accept_q;               /* 1 if an Accept item has a q= param */
  7.     float default_lang_quality; /* fiddle lang q for variants with no lang */
  8.     /* the array pointers below are NULL if the corresponding accept
  9.      * headers are not present
  10.      */
  11.     apr_array_header_t *accepts;            /* accept_recs */
  12.     apr_array_header_t *accept_encodings;   /* accept_recs */
  13.     apr_array_header_t *accept_charsets;    /* accept_recs */
  14.     apr_array_header_t *accept_langs;       /* accept_recs */
  15.     apr_array_header_t *avail_vars;         /* available variants */
  16.     int count_multiviews_variants;    /* number of variants found on disk */
  17.     int is_transparent;       /* 1 if this resource is trans. negotiable */
  18.     int dont_fiddle_headers;  /* 1 if we may not fiddle with accept hdrs */
  19.     int ua_supports_trans;    /* 1 if ua supports trans negotiation */
  20.     int send_alternates;      /* 1 if we want to send an Alternates header */
  21.     int may_choose;           /* 1 if we may choose a variant for the client */
  22.     int use_rvsa;             /* 1 if we must use RVSA/1.0 negotiation algo */
  23. } negotiation_state;

对于协商的表达方式都是一样的,如:

Accept: */*
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7

其中“,”和“;”的分隔或许不太好明白其含义,其实,其格式是这样的:
name;q=N;charset=TEXT
如果要表达多组,则用“,”分隔;如:
name;q=N;charset=TEXT,name;q=N;charset=TEXT

其中,q、charset都是可以省略的,如:
Accept: */*
只有一组说明,而且是省略了q和charset

相关源码参考:
modules/mappers/mod_negotiation.c

  1. typedef struct accept_rec {
  2.     char *name;                 /* MUST be lowercase */
  3.     float quality;
  4.     float level;
  5.     char *charset;              /* for content-type only */
  6. } accept_rec;

关于文档类型的协商依赖的是: docs/conf/mime.types
如:
文档类型                     资源扩展名
text/html                   html htm
text/css                    css
text/plain                  txt text conf def list log in  

关于语言和字符集的协商依赖的是: docs/conf/charset.conv
如:
# Lang-abbv Charset     Language
#———————————
en          ISO-8859-1  English
UTF-8       utf8        UTF-8  
Unicode     ucs         Unicode
th          Cp874       Thai    
ja          SJIS        Japanese
ko          Cp949       Korean  
zh          Cp950       Chinese-Traditional
zh-cn       GB2312      Chinese-Simplified
zh-tw       Cp950       Chinese
。。。

其中,第一列是语言的缩写,协商时一般用缩写; 第二列是字符集

—————————
内容可能是根据多个条件来协商的,那么对于一个协商的资源可能涉及到多个扩展名的,如:
content.en.html.gz
该资源如果写成了:
content.html.en.gz
也是可以找到的,只是在做超链接的时候,如果写成了: content.gz.html.en 就找不到了
参考: http://httpd.apache.org/docs/2.2/content-negotiation.html#naming

关于内容协商与cache
对于http1.0来讲,经过协商的内容是不建议cache的;在http1.1中添加了vary的http头,用来告知客户端内容是根据哪些条件来协商的,这样客户端可以尽可能的利用cache,如果协商条件不变的话就可以使用cache的。

====================
参考资料:

http://httpd.apache.org/docs/2.2/content-negotiation.html
http://httpd.apache.org/docs/2.2/mod/mod_negotiation.html

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据