проблемы с загрузкой файлов на основе формы / фрейма в Opera - PullRequest
1 голос
/ 26 октября 2011

РЕШЕНИЕ

См. Мой ответ ниже: проблемы с загрузкой файлов на основе формы / фрейма в Opera


Я использую технику формы / фреймаотправлять файлы на сервер всякий раз, когда браузер не поддерживает загрузку XMLHttpRequest (Opera).На высоком уровне, вот настройки ...

  1. создать iframe <iframe src="javascript:false;" name="file-iframe"></iframe>
  2. создать форму <form enctype="multipart/form-data" method="POST">
    • установить цель = имя iframe,target="file-iframe"
    • set action = url, action="/upload"
  3. добавить файл ввода в форму
  4. отправить форму

Когда форма отправлена, сервер выплевывает исключение:

org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream.readHeaders(MultipartStream.java:538)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:999)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:965)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.getItemIterator(ServletFileUpload.java:148)
    at com.beamit.jetty.UploadServlet.doPost(UploadServlet.java:28)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    ...
    ...

Вот фрагмент кода в файле UploadServlet.java, где сбой происходит в последней строке фрагмента:

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {

    ServletFileUpload up = new ServletFileUpload();
    try {
        FileItemIterator iter = up.getItemIterator(request); // <------ ERROR
        ...
    } catch (IOException e) {
        e.printStackTrace();
    }
    ...

Я пытался отлаживать это часами, и у меня ничего не получается.Есть идеи, почему это может происходить?

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

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

HTTPзапрос простого текстового файла "hello world" в Chrome .

POST /upload/0145c HTTP/1.1
Host: beamit:8080
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Referer: http://beamit:8080/
Content-Length: 44
Origin: http://beamit:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQes3eWoFE2iw6kGE

HTTP-запрос простого текстового файла "hello world" в Opera .

POST /upload/f889b HTTP/1.1
User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.7.2; U; en) Presto/2.9.168 Version/11.52
Host: beamit:8080
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en,en-US;q=0.9,ja;q=0.8,fr;q=0.7,de;q=0.6,es;q=0.5,it;q=0.4,pt;q=0.3,pt-PT;q=0.2,nl;q=0.1,sv;q=0.1,nb;q=0.1,da;q=0.1,fi;q=0.1,ru;q=0.1,pl;q=0.1,zh-CN;q=0.1,zh-TW;q=0.1,ko;q=0.1,ar;q=0.1,cs;q=0.1,hu;q=0.1,tr;q=0.1
Accept-Encoding: gzip, deflate
Referer: http://beamit:8080/
Cookie: __utma=248039316.1622718495.1317335167.1319648741.1319655028.19; __utmb=248039316.4.10.1319655028; __utmc=248039316; __utmz=248039316.1317335167.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Connection: Keep-Alive
Content-Length: 76
Content-Type: multipart/form-data; boundary=----------cah2BDOhbumylzxVY398ZJ

Ответы [ 2 ]

1 голос
/ 29 октября 2011

Я понял, в чем проблема.После удаления всего ненужного кода и разметки у меня осталась страница загрузки файла формы / iframe.

Когда я строю форму динамически, я вставляю элемент ввода файла как дочерний:

<input type="file" id="file-select-input" />

... и у меня было что-то вроде этого:

<form enctype="multipart/form-data" id="file-select-form" target="select-file-iframe" method="POST" action="/upload/">
    <div id="file-select-button" class="">
        <input type="file" id="file-select-input" />
    </div>
</form>
<iframe style="display: none" id="select-file-iframe" src="javascript:false;" name="select-file-iframe"></iframe>

Эта установка давала мне проблемы.После некоторого расследования выясняется, что когда я отправляю вышеуказанную форму, информация о входном файле не отправлялась.Оказывается, причина этого в том, что у меня не было атрибута name, указанного в элементе ввода файла.Поэтому, когда я изменил это на следующее:

<input type="file" id="file-select-input" name="file" />

... все заработало.

1 голос
/ 26 октября 2011

Данное исключение предполагает, что клиент прервал запрос. Я не уверен в точной причине, но особенно известно, что Opera вызывает проблемы с комбинацией iframes и JavaScript.

Я бы настоятельно рекомендовал взять существующую библиотеку, которая имитирует задание загрузки ajax-файла, а не изобретать велосипед самостоятельно. В истории ваших вопросов я вижу, что вы знакомы с jQuery. Например, вы можете воспользоваться плагином jQuery для создания лучшего кросс-браузерно совместимого волшебства следующим образом:

<script src="jquery.js"></script>
<script src="jquery.form.js"></script>
<script>
    $(document).ready(function() {
        $('#formid').ajaxForm();
    });
</script>
...
<form id="formid">
    <input type="file" name="file" />
    <input type="submit" />
</form>

При необходимости вы можете заглянуть в jquery.form.js источник здесь , чтобы узнать, как они решали проблемы, связанные с браузером.

...