28

Bất kỳ ý tưởng nào về lý do tại sao trên một số liên kết mà tôi cố gắng truy cập bằng cách sử dụng HttpWebRequest Tôi nhận được "Máy chủ từ xa đã trả về lỗi: (304) Không được sửa đổi". trong mã?Tại sao tôi nhận được lỗi "(304) Không được sửa đổi" trên một số liên kết khi sử dụng HttpWebRequest?

Mã tôi đang sử dụng là từ Jeff's post here (trang dường như đã biến mất, xem archive copy at the Wayback Machine).

Lưu ý khái niệm mã là một máy chủ proxy đơn giản, vì vậy tôi chỉ trình duyệt của mình tại đoạn mã đang chạy cục bộ này, yêu cầu trình duyệt của tôi và sau đó tạo proxy mới bằng cách tạo một HttpWebRequest mới sẽ thấy trong mã. Nó hoạt động tốt cho hầu hết các trang web/liên kết, nhưng đối với một số lỗi này xuất hiện. Bạn sẽ thấy một bit quan trọng trong mã là nơi có vẻ như sao chép các thiết lập tiêu đề http từ yêu cầu trình duyệt đến yêu cầu của nó ra ngoài trang web và nó sao chép trong các thuộc tính tiêu đề. Bạn không chắc liệu sự cố có liên quan đến cách bắt chước khía cạnh này của yêu cầu hay không và sau đó điều gì sẽ xảy ra khi kết quả trở lại?

case "If-Modified-Since": 
    request.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]); 
    break; 

tôi nhận được vấn đề ví dụ từ http://en.wikipedia.org/wiki/Main_Page

PS. CẬP NHẬT TẠI ĐÂY

Vẫn không thể làm việc này. Về cơ bản tôi có thể xác định 1 liên kết trong đó có một vấn đề, và nó có vẻ làm việc tốt, lần thứ 2 nó nhận được lỗi, lần thứ 3 OK, lần thứ 4 bị lỗi, lần thứ 5 OK, cứ như là có một số trạng thái không bị xóa hoặc một cái gì đó trong mã. Tôi đã cố gắng để làm sạch mã một chút bằng cách sử dụng "sử dụng" loại báo cáo vv

Đây là mã. Nếu bất cứ ai có thể phát hiện lý do tại sao mỗi lần thứ 2 tôi duyệt đến một liên kết như http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (bắt đầu từ lần thứ 2, không phải là lần đầu tiên) thông qua mã proxy này, tôi nhận được lỗi tôi muốn nghe.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Proxy p = new Proxy(8080); 

     Thread proxythread = new Thread(new ThreadStart(p.Start)); 
     proxythread.Start(); 

     Console.WriteLine("Proxy Started. Press Any Key To Stop..."); 
     Console.ReadKey(); 

     p.Stop(); 
    } 
} 

public class Proxy 
{ 
    private HttpListener _listener; 
    private int _port; 

    public Proxy(int port) 
    { 
     int defaultport = 8080; 

     // Setup Thread Pool 
     System.Threading.ThreadPool.SetMaxThreads(50, 1000); 
     System.Threading.ThreadPool.SetMinThreads(50, 50); 

     // Sanitize Port Number 
     if (port < 1024 || port > 65535) 
      port = defaultport; 

     // Create HttpListener Prefix 
     string prefix = string.Format("http://*:{0}/", port); 
     _port = port; 

     // Create HttpListener 
     _listener = new HttpListener(); 
     _listener.Prefixes.Add(prefix); 
    } 

    public void Start() 
    { 
     _listener.Start(); 

     while (true) 
     { 
      HttpListenerContext request = null; 

      try 
      { 
       request = _listener.GetContext(); 

       // Statistics (by Greg) 
       int availThreads = -1; 
       int compPortThreads = -1; 
       ThreadPool.GetAvailableThreads(out availThreads, out compPortThreads); 
       log("INFO", request.Request.Url.ToString(), "START - [" + availThreads + "]"); 

       ThreadPool.QueueUserWorkItem(ProcessRequest, request); 
      } 
      catch (HttpListenerException ex) 
      { 
       log("ERROR", "NA", "INFO: HttpListenerException - " + ex.Message); 
       break; 
      } 
      catch (InvalidOperationException ex) 
      { 
       log("ERROR", "NA", "INFO: InvalidOperationException - " + ex.Message); 
       break; 
      } 
     } 
    } 

    public void Stop() 
    { 
     _listener.Stop(); 
    } 

    private void log(string sev, string uri, string message) 
    { 
     Console.Out.WriteLine(Process.GetCurrentProcess().Id + " - " + sev + " (" + uri + "): " + message); 
    } 

    private void ProcessRequest(object _listenerContext) 
    { 
     #region local variables 
     HttpWebRequest psRequest;     // Request to send to remote web server 
     HttpWebResponse psResponse;     // Response from remote web server   
     List<byte> requestBody = new List<byte>(); // Byte array to hold the request's body 
     List<byte> responseBody = new List<byte>(); // Byte array to hold the response's body 
     byte[] buffer; 
     string uri = ""; 
     #endregion 

     var listenerContext = (HttpListenerContext)_listenerContext; 
     uri = listenerContext.Request.Url.ToString().Replace(string.Format(":{0}", _port), ""); 

     // Create Interent Request 
     HttpWebRequest internetRequest = (HttpWebRequest)WebRequest.Create(uri); 
     #region Build Request Up 
     internetRequest.Method = listenerContext.Request.HttpMethod; 
     internetRequest.ProtocolVersion = listenerContext.Request.ProtocolVersion; 
     internetRequest.UserAgent = listenerContext.Request.UserAgent; 
     foreach (string key in listenerContext.Request.Headers.AllKeys) 
     { 
      try 
      { 
       switch (key) 
       { 
        case "Proxy-Connection": 
        case "Connection": 
         internetRequest.KeepAlive = (listenerContext.Request.Headers[key].ToLower() == "keep-alive") ? true : false; 
         break; 

        case "Content-Length": 
         internetRequest.ContentLength = listenerContext.Request.ContentLength64; 
         break; 

        case "Content-Type": 
         internetRequest.ContentType = listenerContext.Request.ContentType; 
         break; 

        case "Accept": 
         internetRequest.Accept = listenerContext.Request.Headers[key]; 
         break; 

        case "Host": 
         break; 

        case "Referer": 
         internetRequest.Referer = listenerContext.Request.Headers[key]; 
         break; 

        case "If-Modified-Since": 
         internetRequest.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]); 
         break; 

        default: 
         internetRequest.Headers.Add(key, listenerContext.Request.Headers[key]); 
         break; 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Error settup up psRequest object. Error = " + ex.Message + "\n" + ex.StackTrace); 
      } 
     } 
     #endregion 

     #region Copy content into request 
     buffer = new byte[1024]; 
     using (Stream instream = listenerContext.Request.InputStream) 
     { 
      int incount = instream.Read(buffer, 0, buffer.Length); 
      while (incount > 0) 
      { 
       internetRequest.GetRequestStream().Write(buffer, 0, incount); 
       incount = instream.Read(buffer, 0, buffer.Length); 
      } 
     } 
     #endregion 

     // Get Internet Response 
     HttpWebResponse internetResponse = null; 
     try 
     { 
      using (internetResponse = (HttpWebResponse)internetRequest.GetResponse()) 
      { 
       #region Configure Local Response Header Keys 
       foreach (string key in internetResponse.Headers.Keys) 
       { 
        try 
        { 
         switch (key) 
         { 
          case "Transfer-Encoding": 
           listenerContext.Response.SendChunked = (internetResponse.Headers[key].ToLower() == "chunked") ? true : false; 
           break; 

          case "Content-Length": 
           listenerContext.Response.ContentLength64 = internetResponse.ContentLength; 
           break; 

          case "Content-Type": 
           listenerContext.Response.ContentType = internetResponse.Headers[key]; 
           break; 

          case "Keep-Alive": 
           listenerContext.Response.KeepAlive = true; 
           break; 

          default: 
           listenerContext.Response.Headers.Add(key, internetResponse.Headers[key]); 
           break; 
         } 
        } 
        catch (Exception ex) 
        { 
         log("ERROR", uri, "Error settup up listenerContext.Response objects. Error = " + ex.Message + "\n" + ex.StackTrace); 
        } 
       } 
       #endregion 

       try 
       { 
        // Transfer the body data from Internet Response to Internal Response 
        buffer = new byte[1024]; 
        using (Stream inputStream = internetResponse.GetResponseStream()) 
        { 
         int outcount = inputStream.Read(buffer, 0, buffer.Length); 
         while (outcount > 0) 
         { 
          listenerContext.Response.OutputStream.Write(buffer, 0, outcount); 
          outcount = inputStream.Read(buffer, 0, buffer.Length); 
         } 
        } 
       } 
       catch (Exception ex) 
       { 
        log("ERROR", uri, "Could not obtain response from URI: " + ex.Message); 
       } 
       finally 
       { 
        listenerContext.Response.OutputStream.Close(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      //if (ex is InvalidOperationException || 
      // ex is ProtocolViolationException || 
      // ex is WebException) 
      //{ 
      // log(uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message); 
      // listenerContext.Response.Close(); 
      // return; 
      //} 
      //else { throw; } 

      log("ERROR", uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message); 
      listenerContext.Response.Close(); 
     } 
    } 
} 

Và đây là một ví dụ về những gì tôi nhìn thấy - hit đầu tiên là tốt, 2nd có lỗi ...

Proxy Started. Press Any Key To Stop... 
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50] 
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50] 
2080 - ERROR (http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css): Could not successfully get response: System.Net.WebException - The remote server returned an error: (304) Not Modified. 
+0

bản sao có thể có của [HttpWebRequest.GetResponse ném WebException trên HTTP 304] (http://stackoverflow.com/questions/1366848/httpwebrequest-getresponse-throws-webexception-on-http-304) – Sebastian

Trả lời

66

Thứ nhất, đây không phải là một lỗi. Các 3xx biểu thị một chuyển hướng. Các lỗi thực sự là 4xx (lỗi ứng dụng khách) và 5xx (lỗi máy chủ).

Nếu khách hàng nhận được 304 Not Modified, thì đó là trách nhiệm của khách hàng khi hiển thị danh sách được đề cập từ bộ nhớ cache của chính ứng dụng đó. Nói chung, proxy không nên lo lắng về điều này. Nó chỉ là người đưa tin.

+1

cảm ơn - bạn đang nói thế sau đó, những gì tôi nên làm là bắt ngoại lệ vẫn còn (ngay tại thời điểm tôi đang làm yêu cầu), nhưng sau đó kiểm tra xem những gì là trong trường hợp ngoại lệ và nếu đó là một 304 sau đó chỉ cần tiếp tục? – Greg

+2

Không - nếu bạn đã gửi một if-modified-since hoặc if-none-match, nó ngụ ý bạn có bản sao cục bộ (được lưu trong bộ nhớ cache) - máy chủ đang hướng dẫn bạn sử dụng bản sao đó hàng đầu. – symcbean

+1

OK - chỉ cần đảm bảo tôi đã trả lại mã trạng thái tương tự trong yêu cầu địa phương và điều này dường như hoạt động. Xem http://stackoverflow.com/questions/2611264/httplistener-how-do-i-send-a-webexception-http-304-not-modified-error-back-to để biết thêm chi tiết về mã số – Greg

12

Đây là hành vi dự định.

Khi bạn thực hiện yêu cầu HTTP, máy chủ thường trả về mã 200 OK. Nếu bạn đặt If-Modified-Since, máy chủ có thể trả lại 304 Not modified (và phản hồi sẽ không có nội dung). Điều này được cho là nguyên nhân của bạn rằng trang chưa được sửa đổi.

authors of the class have foolishly decided rằng 304 phải được coi là lỗi và ném ngoại lệ. Bây giờ bạn phải làm sạch sau khi họ bằng cách bắt ngoại lệ mỗi khi bạn cố gắng sử dụng If-Modified-Since.

0

Tôi nghĩ bạn chưa cài đặt các tính năng này. xem dưới đây trong hình.

enter image description here

Tôi cũng gặp vấn đề này một vài ngày trước. Sau khi cài đặt tính năng này thì tôi đã giải quyết nó. Nếu bạn chưa cài đặt tính năng này thì hãy cài đặt nó.

quá trình cài đặt:

  1. đi đến phòng thu android
  2. cụ
  3. Android
  4. SDK Manager
  5. Appearance & Behavior
  6. Android SDK
+1

Không .. đây không phải là câu trả lời –

3

trang Clearing cache trong trình duyệt có thể đạt được trong Firefox hoặc Chrome bằng cách nhấn CTRL + F5 thay vì chỉ nhấn F5

Sau đó bạn có thể thấy 200 câu trả lời thay vì 304 trong trình duyệt F12 công cụ phát triển tab mạng.

Các vấn đề liên quan