Dlaczego dostaję błąd" (304) Not Modified " na niektórych linkach podczas korzystania z HttpWebRequest?

Jakieś pomysły, dlaczego na niektórych linkach, do których próbuję uzyskać dostęp za pomocą HttpWebRequest, dostaję " zdalny serwer zwrócił błąd: (304) Not Modified."w kodzie?

Kod, którego używam, pochodzi z postu Jeffa tutaj (strona wydaje się zniknąć, zobacz kopię archiwum W Wayback Machine ).

Zauważ, że koncepcja kodu jest prostym serwerem proxy, więc kieruję moją przeglądarkę na ten lokalnie działający fragment kodu, który pobiera żądanie przeglądarki, a następnie proxy go tworząc nowy HttpWebRequest, jak widać w kodzie. Działa świetnie dla większości witryn / linków,ale dla niektórych pojawia się ten błąd. Zobaczysz jeden kluczowy bit w kodzie, w którym wydaje się kopiować ustawienia nagłówka http z żądania przeglądarki do żądania na stronę i kopiuje w atrybutach nagłówka. Nie jesteś pewien, czy problem ma coś wspólnego z tym, jak naśladuje ten aspekt żądania, a następnie co się stanie, gdy wynik wróci?

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

I get the wydanie na przykład z http://en.wikipedia.org/wiki/Main_Page

PS. AKTUALIZUJ TUTAJ

Nadal nie mogę tego rozgryźć. Zasadniczo mogę zidentyfikować 1 link, który ma problem, i wydaje się działać dobrze, 2. raz dostaje błąd, 3. raz OK, 4. raz dostaje błąd, 5. raz OK itp. Jakby jakiś stan nie został wyczyszczony lub coś w kodzie. Próbowałem trochę wyczyścić kod za pomocą instrukcji typu "using" itp.

Oto kod. Jeśli ktoś może zauważyć, dlaczego co 2 raz przeglądam link typu http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (zaczynając od drugiego, a nie Pierwszego) za pomocą tego kodu proxy dostaję błąd, który chciałbym usłyszeć.

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();
        }
    }
}

A oto przykład tego, co widzę - pierwsze trafienie jest dobre, drugie ma błąd...

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.
Author: Mormegil, 2010-04-09

4 answers

Po pierwsze, to nie jest błąd. Na 3xx oznacza przekierowanie. Prawdziwymi błędami są 4xx (błąd klienta) oraz 5xx (błąd serwera).

Jeśli klient otrzyma 304 Not Modified, następnie klient jest odpowiedzialny za wyświetlenie danego resouce z własnej pamięci podręcznej. Ogólnie rzecz biorąc, pełnomocnik nie powinien się tym martwić. To tylko posłaniec.

 75
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-08 21:39:15

To jest zamierzone zachowanie.

Gdy wykonujesz żądanie HTTP, serwer zwykle zwraca kod 200 OK. Jeśli ustawisz If-Modified-Since, serwer może zwrócić 304 Not modified (a odpowiedź nie będzie miała zawartości). To ma być twój sygnał, że strona nie została zmodyfikowana.

Autorzy głupio zdecydowali , że 304 należy traktować jako błąd i rzucać wyjątek. Teraz musisz posprzątać po nich, łapiąc wyjątek za każdym razem, gdy próbujesz użyj If-Modified-Since.

 18
Author: Superbest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 03:03:59

Samo naciśnięcie F5 nie zawsze działa.

Dlaczego?

Ponieważ Twój ISP jest również buforowanie danych internetowych dla Ciebie.

Rozwiązanie: Wymuś Odświeżenie.

Wymuś odświeżenie przeglądarki, naciskając CTRL + F5 w Firefoksie lub Chrome, aby wyczyścić pamięć podręczną ISP, zamiast po prostu naciskać F5

Następnie możesz zobaczyć 200 odpowiedzi zamiast 304 w przeglądarce F12 developer tools network zakładka.

Kolejna sztuczka to Dodaj znak zapytania ? na końcu ciągu URL żądanej strony:

http://localhost:52199/Customers/Create?

Znak zapytania zapewni, że przeglądarka odświeży żądanie bez buforowania wcześniejszych żądań.

 12
Author: Ashraf Abusada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 10:50:41

Myślę, że nie zainstalowałeś tych funkcji. patrz poniżej na zdjęciu.

Tutaj wpisz opis obrazka

Ja również cierpiałem na ten problem kilka dni temu. Po zainstalowaniu tej funkcji rozwiązałem ją. Jeśli nie zainstalowałeś tej funkcji, zainstaluj ją.

Proces Instalacji:

  1. przejdź do android studio
  2. Narzędzia
  3. Android
  4. Menedżer SDK
  5. Wygląd I Zachowanie
  6. Android SDK
 -2
Author: Rezaul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 10:52:05