任何想法为什么在我尝试使用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

PS。在这里更新

仍然无法解决这个问题。基本上,我可以识别有问题的1个链接,并且似乎正常工作,第二次会出现错误,第三次好,第四次出现错误,第五次确定等等。代码中的某些内容。我尝试使用“使用”类型语句等来清理代码。

这是代码。如果有人可以发现为什么我第二次我浏览链接 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();
        }
    }
}

这是我看到的示例 - 第一个命中率很好,第二次有错误...

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也为您缓存Web数据。

解决方案: 力刷新。

按下刷新浏览器 Ctrl + 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 Manager
  5. 外观和行为
  6. Android SDK
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top