#php #javascript #internet-explorer-8
#php #javascript #internet-explorer-8
Вопрос:
Я исчерпывающе исследовал эту проблему на stackoverflow, а также на других сайтах. Есть несколько сообщений, касающихся ошибок «отказано в разрешении» в Javascript и IE, но ни одно из них не пролило свет на мою конкретную проблему.
В 2009 году я разработал сайт с использованием PHP для клиента, который помогает им отслеживать запасы продуктов. Одной из предоставляемых функций является возможность создавать новый продукт и назначать изображение, что требует от них загрузки файла изображения. У них также существует возможность редактировать изображение существующего продукта таким же образом. Это делается с помощью всплывающего окна, открывающегося всякий раз, когда пользователь нажимает на кнопку «загрузить» для изображения продукта. Код родительского окна выглядит следующим образом:
function openPopUp( thisForm )
{
var ProductId = thisForm.product_id.value;
var ProductName = thisForm.product_name.value;
var URL = "../imageupload/index.php?product_id=" ProductId "amp;product_name=" ProductName;
var win = window.open ( URL, "imageUploadWindow", "location=0,status=1,scrollbars=1,width=700,height=600,resizeable=1,directories=0,toolbar=0");
win.targetField = thisForm.image;
win.focus();
}
Здесь вызывается функция openPopup():
<form class="productForm" name="form" action="<?php $_SERVER['PHP_SELF'] ?>" method="POST">
...
<td class="maintable"><input type="text" name="image" readonly="readonly" size="20" />
<td class="maintable"><input type="button" value="Upload" name="imageButton" onclick="openPopUp(this.form)" />
...
</form>
Идея, стоящая за этим, заключалась в том, чтобы в родительском окне вводился тип text только для чтения, который принимал бы значение имени файла для изображения. Это имя файла будет передано обратно в родительское окно всплывающим окном после того, как пользователь успешно загрузит изображение. Пользователь закроет всплывающее окно, а затем нажмет кнопку «Обновить» в родительском окне, чтобы отправить обновления продукта (включая имя файла изображения) в базу данных. Для справки, это функция во всплывающем окне, которая передает имя файла обратно родительскому:
function setImageFileName ( fileName )
{
var opener = window.opener;
if ( opener amp;amp; !opener.closed amp;amp; opener.setTargetField )
{
var fileNameShort = /([^\] )$/.exec(fileName)[1];
opener.setTargetField ( targetField, fileNameShort );
}
}
Вот HTML во всплывающем окне для обработки выбора имени файла и загрузки:
<form action="upload.php" method="post" enctype="multipart/form-data">
<p>
<label for="file">Select a new image file:</label> <input type="file" name="imagefile" id="file"> <br />
<button onClick="setImageFileName(this.form.imagefile.value)">Upload File</button>
</p>
</form>
Этот код отлично работает в любом браузере, кроме IE8. Фактически, это ранее работало в IE7, когда я изначально разрабатывал его в 2009 году. Теперь фактически работает только создание нового продукта, хотя HTML, который выводится PHP-скриптом, вызываемым при выполнении загрузки, не отображается в IE (подробнее об этом позже). Основная проблема возникает в IE, когда пользователь нажимает кнопку «загрузить» в родительском окне при редактировании существующего продукта. Консоль скрипта IE отображает ошибку «Отказано в разрешении» в следующей строке:
win.targetField = thisForm.image;
Я перепробовал кучу вещей, в том числе убедился, что проблемы с междоменностью не являются фактором. URL-адреса, открываемые во всплывающем окне, очевидно, находятся в одном домене. Я изменил настройки безопасности в IE на «разрешить междоменный доступ». Любопытно, что проблема «отказано в разрешении» возникает только при редактировании изображения существующего продукта, хотя редактирование существующего и создание нового продукта используют один и тот же Javascript, несмотря на то, что это разные PHP-файлы.
Вторичной по отношению к проблеме «отказано в разрешении» является тот факт, что HTML, отображаемый PHP, выполняющим фактическую загрузку файла, не отображается во всплывающем окне. Вот этот PHP для справки:
if ( move_uploaded_file ( $_FILES['imagefile']['tmp_name'], $realpath . $filename ) )
{
chmod ( $realpath . $filename, 0755 );
echo "Your file upload was successful. New product image:<br /><br />";
echo "<img src="" . $imagePath . $filename . "" alt="New image file" title="New image file" border="0" />";
echo "<p>Remember to click the Update button for this product on the main page to finish your changes.</p>";
echo "<a href="javascript: self.close()">Close</a>";
}
Опять же, это работает должным образом в других браузерах. Когда пользователь нажимает кнопку «загрузить файл» во всплывающем окне, вышеупомянутый PHP выполняется во всплывающем окне и отображается по желанию, но не в IE! Исходный HTML для всплывающего окна остается, создавая впечатление, что загрузка не происходила, но на самом деле это произошло. Все это изначально работало в IE, когда он был впервые разработан.
Я знаю, что это длинный пост, и я, вероятно, все усложняю, но для меня это сбивающая с толку проблема. Надеюсь, это что-то маленькое, чего я просто не вижу. Я ценю любые предложения, которые могут возникнуть у сообщества. Заранее спасибо.
Ответ №1:
В IE8 Microsoft внесла много изменений в систему безопасности, с 1 из которых вы столкнулись.
Вы пытаетесь получить значение поля <input type="file"/>
поля и передать его чему-то другому (в данном случае открывающемуся окну).
Для предотвращения XSS-атак и раскрытия личной информации были внесены изменения, отражающие меры безопасности, применяемые другими браузерами. В результате вы можете обнаружить, что следующие элементы больше не разрешены или строго ограничены.
- Копирование значения filename из поля НЕ разрешено (сравнение с пустой строкой все равно должно работать в целях проверки)
- Ввод имени файла больше не разрешен, вам нужно выбрать файл из средства выбора файлов (останавливает поиск с клавиатуры)
- На стороне сервера вы, очень вероятно, можете получить только имя файла, не полный путь (предотвращает попадание полу-частной информации в руки хакеров (не уверен, что они будут с этим делать, но, увы, это новая норма))
В результате, я думаю, вы попали в пункт № 1 выше, и, таким образом, IE, по сути, выходит из вашего скрипта.