Xpoint
   [напомнить пароль]

Ресайзинг изображений и проблема с IE6

Метки: [без меток]
2008-04-14 11:45:19 [обр] Андрей Анатольич+(0/46)[досье]

На моем сайте изображения ресайзятся на лету. Т.е., есть оригинальное изображение 777.jpg, есть тег на странице:

  <img src="/uploaded/thumbnails/777-100x100.jpg">

При первом обращении по URI /uploaded/thumbnails/777-100x100.jpg из оригинального изображения генерируется тамбнейл, размером 100х100 пикселей.

Вот правило mod_rewrite, которое хэндлит запрос:

RewriteCond  %{REQUEST_FILENAME}  !-f 
RewriteRule  ^uploaded/thumbnails/([0-9x-]+).jpg$ /thumbnails.php?id=$1  [L,QSA]

Проблема
Механизм работает прекрасно во всех браузерах, но в IE при первом обращении к странице изображения не отображаются. Если обновить страницу - изображения появляются.

Да. В скрипте thumbnails.php происходит редирект на тамбнейл, после того, как он сгенерировался. Возможно, проблема именно в этом редиректе?

спустя 7 минут [обр] Алексей В. Иванов(22/2861)[досье]
У меня такая же схема на flagatrip.ru, такой проблемы никогда не было. Исследуйте заголовки.
спустя 30 минут [обр] Андрей Анатольич+(0/46)[досье]

У вас тоже редирект стоит на только что сгенерированный тамбнейл?

Сейчас попробовал сделать не редирект, а readfile(), все прекрасно работает.
При этом, даже с такими заголовками:

http://site.ru:8080/uploaded/thumbnails/6006-80x117.jpg

GET /uploaded/thumbnails/6006-80x117.jpg HTTP/1.1
Host: site.ru:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.13) Gecko/20080311
Accept: image/png,*/*;q=0.5
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0

HTTP/1.x 200 OK
Date: Mon, 14 Apr 2008 08:28:53 GMT
Server: Apache
X-Powered-By: PHP/5.2.5
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=5, max=60
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
спустя 1 час 39 минут [обр] Алексей В. Иванов(22/2861)[досье]
Да, у меня редирект на свежий thumbnail.
Content-Type: text/html ? 8-()
спустя 1 час 55 минут [обр] Андрей Анатольич+(0/46)[досье]

Алексей В. Иванов[досье]
Сейчас заголовки нормальные.

Тот листинг заголовков я привел к тому, что даже так оно работает. А вот с редиректом — нет.

Редирект у ваc такой?

Status: 302 Moved
Location: /some/uri/to/thumbnail.jpg
спустя 55 минут [обр] Marat Tanalin(6/78)[досье]
Попробуйте добавить протокол и домен в Location-заголовок, чтобы URL стал полным, как того требует стандарт:
Location: http://domain.com/some/uri/to/thumbnail.jpg
спустя 5 часов [обр] Алексей В. Иванов(22/2861)[досье]
Редирект у меня обычный, но с полным доменом. Посмотрите, отображаются ли эти картинки в вашем IE6.
спустя 15 часов [обр] Андрей Анатольич+(0/46)[досье]
Попробуйте добавить протокол и домен в Location-заголовок, чтобы URL стал полным, как того требует стандарт
Вот скорее всего в этом и проблема. У меня прописан URI, а не URL. Сейчас попробую исправить.
спустя 35 минут [обр] Андрей Анатольич+(0/46)[досье]

Алексей В. Иванов[досье] Хм. Попробовал, работает в IE, если отдаешь скриптом просто заголовок

Location: http://domain.com/some/uri/to/thumbnail.jpg

Но, при использовании следующего алгоритма — в IE не работает

$thumbnail = generate_thumbnail_if_not_exists();
header("Location: http://domain.com/some/uri/to/{$thumbnail}");

В этом случае IE показывает пустое изображение (в свойствах изображения стоит размер -1 байт). Вообще не понятно, почему такое происходит.

спустя 1 час 41 минуту [обр] Алексей Севрюков(27/1292)[досье]
Андрей Анатольич[досье] А путь точно верный? Посмотрите в свойствах картинки в IE.
спустя 37 минут [обр] Алексей В. Иванов(22/2861)[досье]
а что будет, если header на var_dump заменить?
спустя 31 минуту [обр] Андрей Анатольич+(0/46)[досье]
Алексей Севрюков[досье]
Алексей В. Иванов[досье]
Да, путь правильный, я проверил.
спустя 3 минуты [обр] Алексей Севрюков(27/1292)[досье]
Андрей Анатольич[досье] А если в браузере вводить http://domain.com/some/uri/to/{$thumbnail}? Будет картинка? Это явно какой то баг ИЕ.
спустя 13 часов [обр] Алексей Полушин(13/231)[досье]
Андрей Анатольич[досье] У вас редирект идет ровно на тот же URL, к которому изначально происходит обращение ?
спустя 5 часов [обр] Андрей Анатольич+(0/46)[досье]

Алексей Севрюков[досье]
Да, картинка появится. У меня такое чувство, что когда мы делаем так:

$thumbnail = generate_thumbnail_if_not_exists();
header("Location: http://domain.com/some/uri/to/{$thumbnail}");

и когда происходит редирект, то картинка "не успевает" дописаться на диск, и IE как-то неправильно ее прочитывает. Хотя бред, мне кажется, ведь пока generate_thumbnail_if_not_exists() не вернет результат, следующая операция (отдача заголовка) не должна происходить.

Алексей Полушин[досье] Да, редирект идет на тот же URL.

Через пару часов у меня появится свободное время, я попытаюсь воспроизвести баг и выложить код, чтобы желающий смогли увидеть все в подробностях.

спустя 23 минуты [обр] Андрей Анатольич+(0/46)[досье]

Вот, воспроизвел баг. Сделал небольшой тесь, скачать можно здесь: http://netbranch.ru/files/iebug/iebug.zip

У меня ни в IE6, ни в IE7 изображение не отображается после первой загрузке страницы.

Приведу содержимое файлов моего примера:

.htaccess

RewriteEngine on

RewriteCond  %{REQUEST_FILENAME}  !-f
RewriteRule  ^pics/thumbnail.jpg$  /resize.php

.index.html

<html>
<head>
    <title>Image autoresizing test</title>
</head>

<body style="padding: 250px;">

Эта картинка должна сгенерироваться при первом обращении к этой странице:<br><br>

<img src="/pics/thumbnail.jpg" border="0">

</body>
</html>

resize.php

<?
    // Делаем копию оригинального изображение (Как бы ресайзим =) )
   copy("{$_SERVER['DOCUMENT_ROOT']}/pics/original.jpg", "{$_SERVER['DOCUMENT_ROOT']}/pics/thumbnail.jpg");
   
   // Делаем редирект на полученное изображение
   header("Status: 302 Moved");
   header("Location: http://{$_SERVER['HTTP_HOST']}/pics/thumbnail.jpg");
?>
спустя 38 минут [обр] Алексей Полушин(13/231)[досье]
Не надо делать редирект на самого себя. В этом проблема.
спустя 10 минут [обр] Алексей Полушин(13/231)[досье]

В догонку: получив редирект на тот же url при загрузке изображения, IE не пытается отправить тот же самый запрос на сервер повторно. Причем нельзя сказать, что такое поведение не соответствует стандарту, поскольку

The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request

Что интересно, если этот же url вбить в адресную строку, то при получении редиректа запрос таки отправится второй раз. Особенность реализации, однако.

спустя 44 минуты [обр] Андрей Анатольич+(0/46)[досье]

Алексей Полушин[досье] Значит, получается, единственно правильный метод — отдавать файл сразу в поток, без редиректов?

Алексей В. Иванов[досье]
Вы говорили, на вашем сайте такая схема работает. Мне интересно, как у вас сделано, если она работает? Редирект ведь у вас тоже на самого себя?

спустя 4 минуты [обр] Dennis F. Latypoff aka funky_dennis(3/84)[досье]
header("Location: http://{$_SERVER['HTTP_HOST']}/pics/thumbnail.jpg?{random sequence}");
спустя 37 минут [обр] Алексей Полушин(13/231)[досье]

По ссылке, которую давал Алексей В. Иванов[досье] на запрос http://user.flagatrip.ru/photos/150x150/1.jpg получен ответ

HTTP/1.0 302 Moved Temporarily
Server: nginx/0.5.27
Date: Wed, 16 Apr 2008 03:44:46 GMT
Content-Type: text/html; charset=utf-8
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=m7ak1kfqjjq1trfq8mtn617ko2; path=/; domain=flagatrip.ru
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Location: http://flagatrip.ru/imagecache/0/1/12ad24b2dd448474ab497c26e17120.jpg

Location вовсе не на себя.

спустя 49 минут [обр] Андрей Анатольич+(0/46)[досье]

Алексей Полушин[досье] Интересно.

Стало интересно, как у Алексея Иванова[досье] реврайтится запрос. Что-то пока я не представил этот механизм в общем виде.

спустя 1 час 54 минуты [обр] Алексей Севрюков(27/1292)[досье]

Андрей Анатольич[досье] А если делать внешний редирект, вместо внутреннего?

RewriteRule  ^pics/thumbnail.jpg$  /resize.php [R]

Мне почему то кажется что это решит проблему.

спустя 9 часов [обр] Алексей В. Иванов(22/2861)[досье]

Кстати, да, внешний решний редирект надо попробовать — должно сработать.

У меня обычное правило в .htaccess:

RewriteRule /?(photos)/([0-9]+!?x[0-9]+!?)/(.+)$ image2.php?src=$1/$3&size=$2 [L]

в image2 проверяется, есть ли картинка в кеше и если нет, то создаётся. Имя файла в кеше — md5 от размеров и имени файла. Завершается редиректом на другой url.
Ваш вариат даже поинтересней будет — скрипт не будет лишний раз запускаться.

спустя 7 часов [обр] Алексей Полушин(13/231)[досье]
Ну а чем плохо отдать свежесгенерированый файл скриптом - readfile или fpassthru ?
спустя 2 часа 33 минуты [обр] Алексей Севрюков(27/1292)[досье]
Алексей Полушин[досье] Мне кажется, что отдавать в данном случае файл скриптом - не универсально. Зачем, если это нужно всего один раз. Не вижу смысла писать дополнительный код, пускай он и занимает пару строчек.
спустя 1 день 4 часа [обр] Андрей Анатольич+(0/46)[досье]

Алексей В. Иванов[досье] Спасибо, попробую сделать внешний редирект.

Алексей Полушин[досье] На данный момент отдаю файл при помощи readfile() (скрипт запускается всего один раз, если изображения еще нет).

Powered by POEM™ Engine Copyright © 2002-2005