我尝试使用HttpWebRequest访问某些链接的任何想法我得到"远程服务器返回错误:(304)未修改." 在代码中?
我正在使用的代码来自Jeff的帖子(该页面似乎已经消失,请在Wayback Machine上查看归档副本).
注意代码的概念是一个简单的代理服务器,因此我将浏览器指向这个本地运行的代码片段,它获取我的浏览器请求,然后通过创建新的HttpWebRequest代理它,如您所见代码.它适用于大多数网站/链接,但对于一些人来说,这个错误出现了.您将在代码中看到一个关键位,它似乎将http标头设置从浏览器请求复制到它的请求到网站,并在标头属性中复制.不确定问题是否与它如何模仿请求的这个方面有关,然后结果会发生什么?
case "If-Modified-Since":
request.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]);
break;
Run Code Online (Sandbox Code Playgroud)
我从例如http://en.wikipedia.org/wiki/Main_Page获得了该问题
PS.更新在这里
仍然无法解决这个问题.基本上我可以识别1个有问题的链接,它似乎工作正常,第二次得到错误,第3次OK,第4次得到错误,第5次OK等等好像有一些状态没有被清除或代码中有些东西.我尝试使用"使用"类型语句等来清理代码.
这是代码.如果有人能够发现为什么我每次第二次浏览http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css这样的链接(从第2次开始,而不是第一次)通过这个代理代码,我得到了我想听到的错误.
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); …Run Code Online (Sandbox Code Playgroud) Expressjs自动发送etags.我想知道如何生成etag ..它是基于get例程动态生成的内容.或者我是否可以通过生成内容(动态内容 - 来自DB)并将etag作为相同的内容进行过程来对其进行维护.
可能是一个中间件,它只是检查它是否是有效的会话ID并传回客户端提供的相同etag,或者可能是基于url +会话ID ...这将是唯一的方式.并结束请求,而不是通过整个数据库调用和所有这些东西.在这种情况下,我需要知道客户端正在拨打304电话.
我可以使用expires标签.但是当会话结束时.如果有人打开网址,它不应该允许.所以我认为etag也应该基于会话ID.如何修改可以在此动态内容方案中工作.它可以用吗?
我有一个包含许多小图像(图标)的页面.与chrome一起使用时,每次重新加载页面时,chrome都会使用if-modified-since标头从服务器请求每个图标.
所有图标都配有expires和max-age标头.Firefox从其缓存中加载图像.
为什么Chrome会这样做,我该如何预防?
谢谢
据我了解的规格,RFC 2616(HTTP/1.1)中引入的ETag是Last-Modified-Header的后继产品,它可以让软件架构师更好地控制它.缓存重新验证过程.
如果存在Cache-Validation-Headers(If-None-Match和If-Modified-Since),则根据RFC 2616,客户端(即浏览器)在检查资源时是否应使用ETag.根据RFC 2616的第14.26节,如果If-None-Match-Header中出现的ETag已更改,则服务器不得以304 Not Modified响应,并且服务器必须忽略其他If-Modified-Since-Header ,如果有的话.如果呈现的ETag匹配,则他不得执行请求,除非Last-Modified-Header中的Date表示如此.(如果提供的ETag匹配,服务器应该在GET或HEAD请求的情况下响应304 Not Modified ...)
这部分为一些猜测留下了空间:
...好的当我写这篇文章的时候,问题就是这个答案:
上面提到的(小)矛盾是因为弱ETag.标有弱ETag的资源可能已经改变,尽管ETag没有.因此,在弱ETag的情况下,当ETag没有改变时回答304 Not Modified是错误的,但是If-Modified-Since中呈现的日期不匹配,对吧?
我正在寻找一个试图使用If-Modified-Since请求对象的标头的缓存库.问题是这个标题永远不会被设置,它总是空白的,这对我来说是有意义的,看它是如何请求的.
你怎么能强制要求有一个If-Modified-Since标题?或者我是否会这样做.
这是我指的功能.
public function isNotModified(Request $request)
{
$lastModified = $request->headers->get('If-Modified-Since');
$notModified = false;
if ($etags = $request->getEtags()) {
$notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
} elseif ($lastModified) {
$notModified = $lastModified == $this->headers->get('Last-Modified');
}
if ($notModified) {
$this->setNotModified();
}
return $notModified;
}
Run Code Online (Sandbox Code Playgroud) 似乎有两种不同的方法来使用HTTP头实现条件请求,这两种方法都可以用于缓存,范围请求,并发控制等......:
在这两种情况下,客户端都会发送一条有关资源的信息,这使得服务器可以确定自客户端上次查看资源后资源是否已更改.然后,服务器根据客户端提供的条件头决定是否执行请求.
我不明白为什么有两种不同的方法可供使用.当然,ETags取代时间戳,因为服务器可以很容易地选择从时间戳生成ETag.
所以,我的问题是:
我有一个PHP脚本,使用?img =参数调用.
该参数的值是图像的(urlencoded)URL.
如果该图像已存储在我的服务器上,我的脚本会检查.
如果没有 - 它下载它.之后,它可选择调整图像大小并将其发送到STDOUT,即返回到请求浏览器,前面加上Content-Type和Last-modified标头:
Connection:close
Content-Type:image/jpeg
Date:Fri, 01 Jun 2012 08:28:30 GMT
Last-Modified:Fri, 01 Jun 2012 08:02:44 GMT
Server:Apache/2.2.15 (CentOS)
Transfer-Encoding:chunked
X-Powered-By:PHP/5.3.3
Run Code Online (Sandbox Code Playgroud)
这需要解决一些跨域问题,并且在一年多的时间内对我有用:
但是,我想添加处理传入的If-Modified-since标头的功能 - 发送Not Modified 304响应.
我的问题是:
1)在Apache中运行时,甚至可以在PHP中运行吗?
2)如何处理(即解析和生成)PHP中最好的日期?
奖金问题)如何为调整大小的图像添加Content-Length标头?
我的代码如下(我省略了CURL下载部分):
<?php
define('CACHE_DIR', '/var/www/cached_avatars/');
$img = urldecode($_GET['img']);
$cached = CACHE_DIR . md5($img);
# omitted downloading part for brevity
$readfh = fopen($cached, 'rb');
if ($readfh) {
flock($readfh, LOCK_SH);
$size = getimagesize($cached);
$w = $size[0]; …Run Code Online (Sandbox Code Playgroud) 我发现第二次播放视频时Edge不起作用.我的应用程序使用默认<video>标记,Edge If-Modified-Since在第二次加载视频时发送标题.如果我的服务器返回304 Not-Modified它不起作用.当我更改它以返回完整的视频时,它可以工作.
任何可以验证此行为的人?我做错了什么,我应该在304响应中添加其他内容以使其正常工作吗?
顺便说一句,我看到Chrome和Firefox等其他浏览器If-Modified-Since在加载视频时从未发送过.
PHP引擎如何处理仅在文件扩展名方面不同的相同文件之间似乎存在问题.
问题:"If-Modified-Since条件请求返回完整内容不变."
此外,我测量.php扩展加载比带有.xxx扩展的identitcal twin快得多,即使文件内容相同,并且它们的文件扩展名也不同.


"HTTP允许客户端发出条件请求以查看它们所持有的副本是否仍然有效.由于此响应具有Last-Modified标头,因此客户端应该能够使用If-Modified-Since请求标头进行验证.RED已完成这发现资源发送完整的响应,即使它没有改变,表明它不支持Last-Modified验证."
.php
.ast
鉴于:
home.php文件被复制为home.xxx,此扩展名被添加到htaccess以将其识别为PHP文件..php文件监听php.ini,其中新鲜度设置为3小时,非.php文件必须监听htaccess,其中新鲜度设置为2小时,具体如下:
AddType application/x-httpd-php .php .ast .abc .xxx .etc
<IfModule mod_headers.c>
ExpiresActive On
ExpiresDefault M2419200
Header unset ETag
FileETag None
Header unset Pragma
Header set Cache-Control "max-age=2419200"
##### DYNAMIC PAGES
<FilesMatch "\\.(ast|php|abc|xxx)$">
ExpiresDefault M7200
Header set Cache-Control "public, max-age=7200"
</FilesMatch>
</IfModule>
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好并且所有东西都加载了,除了非php文件没有正确缓存,或者它确实缓存但是不能很好地验证,更具体.见附件图片.只有非php文件扩展名会导致错误并加载更慢.
整个page.php加载速度更快,因为其中的所有元素然后从缓存中正确加载,而page.abc在应该缓存时返回完整请求,这意味着整个页面速度较慢.
底线:应该更改什么,以便消除If-Modified-Since条件请求返回完整内容不变?
我想在我的API中实现"获取更改值"功能.例如,假设我有以下REST API调用:
GET /ws/school/7/student
Run Code Online (Sandbox Code Playgroud)
这让所有学生都在学校#7.不幸的是,这可能很多.因此,我想修改API以仅返回自特定时间以来已修改的学生记录.(用例是夜间进程从另一个系统运行,将所有学生从我的系统中拉到他们的系统.)
我看到http://blog.mugunthkumar.com/articles/restful-api-server-doing-it-the-right-way-part-2/建议使用if-modified-since标头并返回如下表示:
我理解他想做什么,但这似乎是错误的方法.If-Modified-Since标题的定义(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24)说:
If-Modified-Since请求标头字段与方法一起使用以使其成为条件:如果请求的变体自该字段中指定的时间以来未被修改,则不会从服务器返回实体; 相反,将返回304(未修改)响应,而不返回任何消息体.
这对我来说似乎不对.我们不会返回RFC所示的表示或304,而是一些混合.看起来客户端代码(或者更糟糕的是,服务器和客户端之间的Web缓存)可能会错误地解释其含义并替换本地缓存值,而它应该只是更新它.
那么,有两个问题:
http ×5
etag ×3
php ×3
caching ×2
rest ×2
express ×1
html5 ×1
http-headers ×1
outputcache ×1
validation ×1
video ×1