لماذا أحصل على خطأ "(304) غير معدّل" في بعض الروابط عند استخدام httpwebrequest؟

StackOverflow https://stackoverflow.com/questions/2603595

سؤال

أي أفكار لماذا في بعض الروابط التي أحاول الوصول إليها باستخدام httpwebrequest ، أحصل على "أن الخادم البعيد أعاد خطأ: (304) لم يتم تعديله." في الكود؟

الرمز الذي أستخدمه هو من منشور جيف هنا (يبدو أن الصفحة قد اختفت ، انظر أرشيف نسخة في آلة Wayback).

لاحظ أن مفهوم الكود هو خادم وكيل بسيط ، لذلك أشير إلى متصفحي في قطعة الكود التي تعمل محليًا ، والتي تحصل على طلب المتصفحات الخاص بي ، ثم يتم وضعه على ذلك عن طريق إنشاء httpwebrequest جديد ، كما سترى في الرمز. إنه يعمل بشكل رائع لمعظم المواقع/الروابط ، ولكن بالنسبة لبعض هذا الخطأ يأتي. سترى جزء مفتاح واحد في الكود هو المكان الذي يبدو فيه نسخ إعدادات رأس HTTP من طلب المتصفح إلى طلبه إلى الموقع ، ويقوم بنسخ في سمات الرأس. لست متأكداً مما إذا كانت المشكلة تتعلق بكيفية تحاكي هذا الجانب من الطلب ومن ثم ما يحدث مع عودة النتيجة؟

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

أحصل على المشكلة على سبيل المثال من http://en.wikipedia.org/wiki/main_page

ملاحظة. تحديث هنا

ما زلت لا أستطيع العمل هذا. في الأساس ، يمكنني تحديد رابط واحد له مشكلة ، ويبدو أنه يعمل بشكل جيد ، المرة الثانية التي يحصل فيها على الخطأ ، الوقت الثالث على ما يرام ، المرة الرابعة تحصل على الخطأ ، المرة الخامسة على ما يرام. شيء ما في الكود. لقد حاولت تنظيف الكود قليلاً باستخدام عبارات النوع "باستخدام" وما إلى ذلك.

ها هو الرمز. إذا كان بإمكان أي شخص تحديد سبب كل مرة أتصفح فيها رابط مثل http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css (بدءًا من المرة الثانية ، وليس الأول) عبر رمز الوكيل هذا ، أحصل على الخطأ الذي أحب أن أسمعه.

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

وهنا مثال على ما أراه - أول ضربة جيدة ، 2nd لديها خطأ ...

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.
هل كانت مفيدة؟

المحلول

أولاً ، هذا ليس خطأ. ال 3xx يدل على إعادة التوجيه. الأخطاء الحقيقية 4xx (خطأ العميل) و 5xx (خطأ في الخادم).

إذا حصل العميل على ملف 304 Not Modified, ، عندها تقع على عاتق العميل مسؤولية عرض إعادة الاستعادة المعنية من ذاكرة التخزين المؤقت الخاصة بها. بشكل عام ، لا ينبغي أن يقلق الوكيل بشأن هذا. إنه مجرد رسول.

نصائح أخرى

هذا هو السلوك المقصود.

عند تقديم طلب HTTP ، يقوم الخادم عادة بإرجاع التعليمات البرمجية 200 OK. إذا قمت بتعيين If-Modified-Since, ، قد يعود الخادم 304 Not modified (والاستجابة لن تحتوي على المحتوى). من المفترض أن يكون هذا هو جديلة أن الصفحة لم يتم تعديلها.

ال لقد قرر مؤلفو الفصل بحماقة الذي - التي 304 يجب أن تعامل كخطأ ورمي استثناء. الآن عليك التنظيف من خلال اللحاق بالاستثناء في كل مرة تحاول استخدامها If-Modified-Since.

مجرد الضغط F5 لا يعمل دائما.

لماذا ا؟

لأن ISP الخاص بك يقوم أيضًا بتخزين بيانات الويب لك.

المحلول: القوة تحديث.

إجبار تحديث متصفحك بالضغط كنترول + F5 في Firefox أو Chrome لمسح ذاكرة التخزين المؤقت ISP أيضًا ، بدلاً من الضغط فقط F5

يمكنك بعد ذلك رؤية 200 استجابة بدلاً من 304 في المتصفح F12 علامة تبويب شبكة أدوات المطور.

خدعة أخرى هي إضافة علامة استفهام ? في نهاية سلسلة عنوان URL للصفحة المطلوبة:

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

ستضمن علامة الاستفهام أن المتصفح ينشط الطلب دون تخزين أي طلبات سابقة.

بالإضافة إلى ذلك استوديو مرئي يمكنك تعيين المستعرض الافتراضي ل كروم في التخفي وضع لتجنب مشكلات ذاكرة التخزين المؤقت أثناء التطوير ، عن طريق إضافة Chrome في وضع التخفي كمتصفح افتراضي ، راجع الخطوات (الموضحة ذاتيًا):

Go to browsers list Select browse with... Click Add... Point to the chrome.exe on your platform, add argument "Incognito" Choose the browser you just added and set as default, then click browse

أعتقد أنك لم تقم بتثبيت هذه الميزات. انظر أدناه في الصورة.

enter image description here

كما عانيت من هذه المشكلة قبل بضعة أيام. بعد تثبيت هذه الميزة ثم قمت بحلها. إذا لم تكن قد قمت بتثبيت هذه الميزة ثم قمت بتثبيتها.

عملية التثبيت:

  1. انتقل إلى Android Studio
  2. أدوات
  3. ذكري المظهر
  4. مدير SDK
  5. المظهر والسلوك
  6. أندرويد سك
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top