Присвоение переменной Javascript для всплывающего окна приводит к ошибке «Отказано в разрешении» в IE8

#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-атак и раскрытия личной информации были внесены изменения, отражающие меры безопасности, применяемые другими браузерами. В результате вы можете обнаружить, что следующие элементы больше не разрешены или строго ограничены.

  1. Копирование значения filename из поля НЕ разрешено (сравнение с пустой строкой все равно должно работать в целях проверки)
  2. Ввод имени файла больше не разрешен, вам нужно выбрать файл из средства выбора файлов (останавливает поиск с клавиатуры)
  3. На стороне сервера вы, очень вероятно, можете получить только имя файла, не полный путь (предотвращает попадание полу-частной информации в руки хакеров (не уверен, что они будут с этим делать, но, увы, это новая норма))

В результате, я думаю, вы попали в пункт № 1 выше, и, таким образом, IE, по сути, выходит из вашего скрипта.