0

我尝试仅使用 javascript 发送带有文件的多部分表单数据。我自己写请求。所以我的javascript代码如下:

var data =
    '------------f8n51w2QYCsvNftihodgfJ\n' +
    'Content-Disposition: form-data; name="upload-id"\n' +
    '\n' +
    'uploadedFiles\n' +
    '------------f8n51w2QYCsvNftihodgfJ\n' +
    'Content-Disposition: form-data; name="file"; filename="doc1.txt"\n' +
    'Content-Type: text/plain\n' +
    '\n' +
    'azerty\n' +
    '------------f8n51w2QYCsvNftihodgfJ--\n';

    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload');
    xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=----------f8n51w2QYCsvNftihodgfJ');
    xhr.sendAsBinary(data);

我在 Firefox 18 上运行这个 javascript。所以我在/upload. 这是代码:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    RequestContext request_context = new ServletRequestContext(request);
    boolean is_multipart = ServletFileUpload.isMultipartContent(request_context);
    if (is_multipart) {
        FileUpload file_upload = new FileUpload(fileItemFactory);
        List<FileItem> file_items = file_upload.parseRequest(request_context); // This line crash
    }
}

正如评论所说,线路file_upload.parseRequest(request_context);崩溃并引发以下异常:

org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream.readHeaders(MultipartStream.java:539)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:976)
    at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:942)
    at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:349)

而且我只是不知道为什么我得到了这个例外......知道吗?

似乎MultipartStream找不到请求标头。但是,如果我记录标题,它们都在这里并且它们是正确的。

我的 servlet 代码使用“正常”形式。我尝试记录普通形式的请求正文和标头,它们是相同的(当然边界除外)。

我还尝试data使用无效内容更改变量。错误仍然相同,所以我的标题肯定有问题,但我看不出是什么。

4

3 回答 3

2

我找到了解决方案。

\n 不是多部分表单的有效分隔符。您必须使用\r\n. 现在我的代码可以正常工作了。

于 2013-02-19T11:22:41.237 回答
0

我不明白你为什么使用sendAsBinary. 如果不是绝对必要,我不会自己组装有效载荷(data变量),而是使用FormData.

https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/FormData/Using_FormData_Objects

var oMyForm = new FormData();

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"

// HTML file input user's choice...
oMyForm.append("userfile", fileInputElement.files[0]);

// JavaScript file-like object...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var oBlob = new Blob([oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob);

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);
于 2013-02-19T10:39:42.960 回答
0

尝试将f8n51w2QYCsvNftihodgfJ更改为f8n51w2QYCsvNftihodgfM

我试过用不同的随机边界运行你的代码,结果只有f8n51w2QYCsvNftihodgfJ\n有问题。我认为您可以尝试不同的边界,因为它实际上只是一个随机字符串。

于 2013-02-19T10:45:12.367 回答