Какие методы позволяют обойти правила безопасности загрузки файлов IE? - PullRequest
11 голосов
/ 14 января 2010

Internet Explorer (с настройками по умолчанию, которые, как я обычно предполагаю, будут действовать на рабочих столах Великого Немытых), похоже, не любит идею принятия содержимого вложения в ответ HTTP, если соответствующий запрос не был сделан непосредственно из действие пользователя (например, обработчик «щелчка» или отправка собственной формы). Возможно, есть больше деталей и нюансов, но это основное поведение, которое меня расстраивает.

Мне кажется, что это обычная ситуация: пользовательский интерфейс перед загружаемым контентом & mdash; скажем, подготовленный отчет в формате PDF & mdash; позволяет использовать некоторые параметры и входные данные при создании контента. Теперь, как и во всех формах, которые позволяют пользователю определять, как приложение что-то делает, возможно, что ввод будет ошибочным. Не всегда, но иногда.

Таким образом, возникает дилемма. Если клиент пытается сделать что-то необычное, например, выполнить транзакцию AJAX, чтобы позволить серверу проверить содержимое формы, а затем повторно отправить его для загрузки, IE это не понравится. Это не понравится, потому что фактическая HTTP-транзакция, которая возвращает вложение, будет происходить не в исходном обработчике пользовательского действия, а в обратном вызове завершения AJAX. Хуже того, поскольку панель безопасности IE, кажется, думает, что решение всех проблем состоит в том, чтобы просто перезагрузить внешнюю страницу с ее исходного URL-адреса, его приглашение пользователю продолжить загрузку подозрительного контента даже не будет работать.

Другой вариант - просто запустить форму. Сервер проверяет параметры, и, если что-то не так, он отвечает страницей контейнера формы, соответствующим образом пересылаемой сообщениями об ошибках. Если содержимое формы в порядке, оно генерирует содержимое и отправляет его обратно в ответ HTTP в виде вложенного файла. В этом случае (я думаю), IE доволен, потому что контент, по-видимому, был напрямую запрошен пользователем (что, кстати, является нелепо ненадежным способом отличить хороший контент от плохого). Это замечательно, но проблема в том, что клиентская среда (то есть код на моей странице) не может сказать, что загрузка работала, поэтому форма все еще находится там. Если моя форма находится в каком-то диалоговом окне, мне действительно нужно закрыть ее после завершения операции & mdash; на самом деле, это одна из причин, почему AJAX делает это.

Мне кажется, что единственное, что нужно сделать, это снабдить диалоги форм сообщениями, в которых говорится что-то вроде: «Закройте это, когда начнется загрузка». Это действительно кажется мне неубедительным, потому что это пример интерфейса «пожалуйста, нажмите эту кнопку для меня»: в идеале, мой собственный код должен иметь возможность нажимать кнопку, когда это необходимо. Ключевой момент, который я не знаю, это то, что клиентский код может обнаружить, что отправка формы привела к загрузке вложения. Я никогда не слышал о способе обнаружить это, но это сломало бы для меня тупик.

Ответы [ 3 ]

8 голосов
/ 14 января 2010

Я так понимаю, вы отправляете форму с другим целевым окном; следовательно форма остается на месте.

Есть несколько вариантов.

  1. Держите кнопку отправки отключенной и выполняйте текущую проверку в фоновом режиме, опрашивая форму на предмет изменений полей, а затем запуская запрос проверки для поля по мере его изменения. Когда форма находится в действительном состоянии, включите кнопку; когда это не так, отключите кнопку. Это не идеально, так как это может привести к задержке, но может быть достаточно для того, что вы делаете.
  2. Выполните базовую проверку, которая не требует обращения к серверу в обработчике для события submit формы, затем отправьте форму и удалите ее (или, возможно, просто спрячьте). Если дальнейшая проверка на сервере обнаружит проблему, он может вернуть страницу, которая использует JavaScript, чтобы сообщить исходному окну о повторном отображении формы.
  3. Использовать куки-файл сессии и уникальный идентификатор формы (текущее время с new Date().getTime() подойдет); когда форма отправлена, отключите ее кнопку отправки, но оставьте ее видимой, пока ответ не вернется. Сделайте так, чтобы в ответе был установлен сеансовый куки-файл с идентификатором, указывающим на успех / неудачу. Окно, содержащее опрос формы для куки, каждую секунду или около того, и воздействуйте на результат, когда он его видит. (Я никогда не делал этого в последний раз; не сразу понимая, почему это не сработает.)

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

(Изменить) Если вы не отправляете другой цели, вы можете пойти дальше и сделать это - для скрытого iframe на той же странице. Это (возможно, в сочетании с приведенными выше или другими ответами) может помочь вам получить пользовательский опыт, который вы ищете.

2 голосов
/ 14 января 2010

Есть целый ряд действительно веских причин IE делает это, и я уверен, что с этим никто не поспорит - поэтому главная цель - как-то обойти это, чтобы сделать вещи лучше для вашего пользователи.

Иногда стоит переосмыслить, как все делается. Возможно, отключите кнопку, используйте javascript, чтобы проверить, когда все поля заполнены, и запустите ajax-запрос, как только они появятся. Если ajax прошел успешно, включите кнопку. Это всего лишь одно предложение, я уверен, что будет больше ...

Редактировать: подробнее ...

Выполните простую отправку (не AJAX), и, если проверки не пройдены, отправьте страницу назад, а не вложение. Отправленная страница может содержать всю первоначально отправленную информацию (плюс любое сообщение об ошибке пользователю), поэтому пользователю не нужно снова заполнять всю форму. И я также уверен, что будет больше идей ...

Редактировать: подробнее ...

Я уверен, что вы уже видели подобные вещи раньше - и да, это - это дополнительный щелчок (не идеально, но не сложно) .... an "если загрузка не удалась, нажмите здесь "-> в этом случае сделайте это так, как вы хотите, но добавьте новую ссылку / кнопку на страницу, когда AJAX вернется, поэтому, если загрузка не удалась, они могут отправить уже проверенную форму из" прямой действие пользователя ". И я уверен, что я буду думать больше (или кто-то еще будет) .....

1 голос
/ 12 декабря 2017

Я боролся с подобной проблемой некоторое время. В моем случае публикация в скрытый iframe не работала, если мое веб-приложение было встроено в iframe на другом сайте (проблемы с файлами cookie третьих сторон), если только наш сайт не был добавлен в список надежных сайтов.

Я обнаружил, что могу разбить загрузку на последовательность POST и GET. Сообщение возвращает недолговечный GUID, который можно использовать в GET-запросе для запуска загрузки. POST может выполнить проверку формы, а также вернуть GUID в успешном ответе. Когда у клиента есть GUID, вы можете установить для свойства src скрытого элемента iframe URL-адрес загрузки. Браузер видит заголовок «Content-Disposition»: «Attachement» и предоставляет пользователю ленту для загрузки файла.

Пока что он работает во всех последних браузерах. К сожалению, для загрузки файла требуется изменить API на стороне сервера.

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