<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      http響應Last-Modified和ETag以及asp.net web api實現

      基礎知識
      1) 什么是”Last-Modified”?
      在瀏覽器第一次請求某一個URL時,服務器端的返回狀態會是200,內容是你請求的資源,同時有一個Last-Modified的屬性標記此文件在服務期端最后被修改的時間,格式類似這樣:
      Tue, 24 Apr 2012 13:53:56 GMT

      客戶端第二次請求此URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送 If-Modified-Since 報頭,詢問該時間之后文件是否有被修改過:
      If-Modified-Since: Tue, 24 Apr 2012 13:53:56 GMT

      如果服務器端的資源沒有變化,則自動返回 HTTP 304 (Not Changed.)狀態碼,內容為空,這樣就節省了傳輸數據量。當服務器端代碼發生改變或者重啟服務器時,則重新發出資源,返回和第一次請求時類似。從而保證不向客戶端重復發出資源,也保證當服務器有變化時,客戶端能夠得到最新的資源。
      2) 什么是”Etag”?
      HTTP 協議規格說明定義ETag為“被請求變量的實體值” 。 另一種說法是,ETag是一個可以與Web資源關聯的記號(token)。典型的Web資源可以一個Web頁,但也可能是JSON或XML文檔。服務器單獨負責判斷記號是什么及其含義,并在HTTP響應頭中將其傳送到客戶端,以下是服務器端返回的格式:
      "9077da2dec72bbb7151a6579fa214de0"

      客戶端的查詢更新格式是這樣的:
      "9077da2dec72bbb7151a6579fa214de0"

      如果ETag沒改變,則返回狀態304然后不返回,這也和Last-Modified一樣。

      Last-Modified和Etags如何幫助提高性能?
      聰明的開發者會把Last-Modified 和ETags請求的http報頭一起使用,這樣可利用客戶端(例如瀏覽器)的緩存。因為服務器首先產生 Last-Modified/Etag標記,服務器可在稍后使用它來判斷頁面是否已經被修改。本質上,客戶端通過將該記號傳回服務器要求服務器驗證其(客戶端)緩存。

      過程如下:
      1,客戶端請求一個頁面(A)。

      2,服務器返回頁面A,并在給A加上一個Last-Modified/ETag。

      3,客戶端展現該頁面,并將頁面連同Last-Modified/ETag一起緩存。

      4,客戶再次請求頁面A,并將上次請求時服務器返回的Last-Modified/ETag一起傳遞給服務器。

      5,服務器檢查該Last-Modified或ETag,并判斷出該頁面自上次客戶端請求之后還未被修改,直接返回響應304和一個空的響應體。

      正確使用Etag和Expires標識處理,可以使得頁面更加有效被Cache。
      在客戶端通過瀏覽器發出第一次請求某一個URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送報頭(Http Request Header),服務器端響應同時記錄相關屬性標記(Http Reponse Header),服務器端的返回狀態會是200,格式類似如下:

      HTTP/1.1 200 OK
      Cache-Control: public, max-age=1728000
      Transfer-Encoding: chunked
      Content-Type: image/jpeg
      Expires: Sun, 20 May 2012 16:26:22 GMT
      Last-Modified: Tue, 24 Apr 2012 13:53:56 GMT
      ETag: "9077da2dec72bbb7151a6579fa214de0"
      Server: Microsoft-IIS/7.5
      X-AspNet-Version: 4.0.30319
      X-Powered-By: ASP.NET
      Date: Mon, 30 Apr 2012 16:26:22 GMT

      客戶端第二次請求此URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送報頭(Http Request Header),服務器端響應并記錄相關記錄屬性標記文件沒有發生改動,服務器端返回304,直接從緩存中讀取:

      HTTP/1.1 304 Not Modified
      Cache-Control: no-cache
      Pragma: no-cache
      Expires: -1
      Server: Microsoft-IIS/7.5
      X-AspNet-Version: 4.0.30319
      X-Powered-By: ASP.NET
      Date: Mon, 30 Apr 2012 16:30:06 GMT

       

      asp.net web api的實現代碼如下:

      // GET /img/2012031023134652.png
              [HttpGet]
              public HttpResponseMessage Get([FromUri]string filename)
              {
                  HttpResponseMessage response = new HttpResponseMessage();  

                  MongoFSDirectory fs = new MongoFSDirectory(new MongoFSDirectoryParameters() { ConnectionString = this.ConnectionString });
                  MongoGridFSFileInfo fileInfo = fs.GetFileInfo(filename);
                  if (fileInfo == null)
                  {
                      throw new HttpResponseException("The file does not exist.", HttpStatusCode.NotFound);
                  }
                  string etag = string.Format("\"{0}\"", fileInfo.MD5);
                  var tag = Request.Headers.IfNoneMatch.FirstOrDefault();
                  if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag == etag)
                  {
                      response.StatusCode = HttpStatusCode.NotModified;
                  }
                  else
                  {
                      MemoryStream responseStream = new MemoryStream();
                      MongoGridFSStream gfs = fileInfo.OpenRead();

                      bool fullContent = true;
                      if (this.Request.Headers.Range != null)
                      {
                          fullContent = false;
                          // Currently we only support a single range.
                          RangeItemHeaderValue range = this.Request.Headers.Range.Ranges.First();

                          // From specified, so seek to the requested position.
                          if (range.From != null)
                          {
                              gfs.Seek(range.From.Value, SeekOrigin.Begin);

                              // In this case, actually the complete file will be returned.
                              if (range.From == 0 && (range.To == null || range.To >= gfs.Length))
                              {
                                  gfs.CopyTo(responseStream);
                                  fullContent = true;
                              }
                          }
                          if (range.To != null)
                          {
                              // 10-20, return the range.
                              if (range.From != null)
                              {
                                  long? rangeLength = range.To - range.From;
                                  int length = (int)Math.Min(rangeLength.Value, gfs.Length - range.From.Value);
                                  byte[] buffer = new byte[length];
                                  gfs.Read(buffer, 0, length);
                                  responseStream.Write(buffer, 0, length);
                              }
                              // -20, return the bytes from beginning to the specified value.
                              else
                              {
                                  int length = (int)Math.Min(range.To.Value, gfs.Length);
                                  byte[] buffer = new byte[length];
                                  gfs.Read(buffer, 0, length);
                                  responseStream.Write(buffer, 0, length);
                              }
                          }
                          // No Range.To
                          else
                          {
                              // 10-, return from the specified value to the end of file.
                              if (range.From != null)
                              {
                                  if (range.From < gfs.Length)
                                  {
                                      int length = (int)(gfs.Length - range.From.Value);
                                      byte[] buffer = new byte[length];
                                      gfs.Read(buffer, 0, length);
                                      responseStream.Write(buffer, 0, length);
                                  }
                              }
                          }
                      }
                      // No Range header. Return the complete file.
                      else
                      {
                          gfs.CopyTo(responseStream);
                      }
                      gfs.Close();
                      responseStream.Position = 0;
                      response.StatusCode = fullContent ? HttpStatusCode.OK : HttpStatusCode.PartialContent;
                      response.Content = new StreamContent(responseStream);
                      response.Content.Headers.ContentType = new MediaTypeHeaderValue(fileInfo.ContentType);
                      response.Headers.ETag = new EntityTagHeaderValue(etag);
                      response.Headers.CacheControl = new CacheControlHeaderValue();
                      response.Headers.CacheControl.Public = true;
                      response.Headers.CacheControl.MaxAge = TimeSpan.FromHours(480);
                      response.Content.Headers.Expires = DateTimeOffset.Now.AddDays(20);
                      response.Content.Headers.LastModified = fileInfo.UploadDate;
                  }
                  return response;

              }

      參考:

      sample message handler for managing etags in web api

      http://codepaste.net/4w6c6i

      posted @ 2012-05-01 00:45  張善友  閱讀(6841)  評論(10)    收藏  舉報
      主站蜘蛛池模板: 亚洲人成亚洲人成在线观看| 综合在线 亚洲 成人 欧美 | 欧美成人精品一级在线观看| 国产香蕉尹人在线视频你懂的| 亚洲av成人免费在线| 国产一区二区三区不卡视频| 亚洲V天堂V手机在线| 亚洲欧美自偷自拍视频图片| 丝袜美腿视频一区二区三区| 久久超碰色中文字幕超清| 亚洲自偷自拍熟女另类| 视频一区二区三区四区五区| 唐人社视频呦一区二区| 伊人精品成人久久综合| 男人用嘴添女人私密视频| 99riav国产精品视频| 国产真实露脸乱子伦原著| 一区二区三区激情免费视频| 国产成人综合在线女婷五月99播放| 377P欧洲日本亚洲大胆| 婷婷六月综合缴情在线| 少妇人妻偷人免费观看| 日韩女同一区二区三区久久| 亚洲欧美色综合影院| 丰满少妇熟乱xxxxx视频| AV人摸人人人澡人人超碰| 国产精品美女免费无遮挡| 干中文字幕| 亚洲理论在线A中文字幕| 日韩av在线不卡一区二区三区| 日韩久久久久久中文人妻| 国产精品中文字幕二区| 精品国产午夜理论片不卡| 国产亚洲精品日韩香蕉网| 欧美裸体xxxx极品| 四虎国产精品久久免费精品| 亚洲精品岛国片在线观看| 国产精品麻豆va在线播放| 无码日韩做暖暖大全免费不卡| 亚洲精品无码成人aaa片| 蜜臀在线播放一区在线播放|