簡體   English   中英

NanoHTTPD:使用html表單上傳文件(POST)

[英]NanoHTTPD: upload a file using a html form (POST)

我在Java桌面環境中使用NanoHTTPD webserver 2.1.0。 (沒有Android)

一切正常......但不是使用POST方法上傳文件(表格不支持PUT)

這是我的HTML代碼:

<form method="post" enctype="multipart/form-data">
    choose a file<br>
    <input name="file" type="file" size="50" maxlength="100000"">
    <button type="submit">upload</button>
</form>

這是我的服務器方法:

public Response serve(IHTTPSession session) {
    if (session.getMethod() == Method.POST) {
        Map<String, String> files = new HashMap<String, String>();
        session.parseBody(files);
        //this prints {file=C:\path-to-java-tmp-files\NanoHTTPD-4635244586997909485}
        //the number is always different
        System.out.println(files.toString());
    } else {
        //page containing the index.html including the form
        return page;
    }
}

這是問題:臨時文件不存在。 現有的另一個臨時文件具有不同的“數字”,這似乎是正確的文件,因為內容與上傳文件的內容相同。 那么如何獲得正確的臨時文件名呢?

另一個問題是:臨時文件包含漏洞POST內容:

-----------------------------115801144322347
Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: application/octet-stream

-->content of the uploaded file


-----------------------------115801144322347--

如果內容是pic或二進制文件,則這是一個問題。

似乎NanoHTTPD不會對POST請求做任何特殊操作。 它總是一樣...將請求保存到tmp文件並提供頁面。 所以: - 如何獲得正確的臨時文件? - >我認為這是一個bug。 我得到了正確的路徑和名稱,但“數字”已被破壞。 idk ...如果發生上傳,我應該暫時更改java tmp-path,然后始終刪除該文件。 那么我只有一個tmp文件獨立於任何命名? - 如何從文件中刪除html請求標頭

或者我做錯了什么? 這是將文件上傳到nanohttpd的正確方法嗎?

謝謝你的幫助!

在我發布“你找到了解決辦法嗎?”之后不久就弄明白了。 問題,但忘記發布,直到你今天回復。

<form method="post" enctype="multipart/form-data" action="http://whatever.com/path/">
    <input type="file" name="file" />
    <input type="hidden" name="extra_data" value='blah blah blah' />
    <input type="submit" value="Send" />
</form>

和Java代碼:

if (session.getMethod() == Method.POST) {
    try { session.parseBody(files); }
    catch (IOException e1) { e1.printStackTrace(); }
    catch (ResponseException e1) { e1.printStackTrace(); }

    extraData = session.getParms().get("extra_data");
    File file = new File(files.get("file"));
}

重要的是,您發送的數據帶有文件數據,文件名和文件mime類型。

在我的情況下,我使用python請求POST並沒有發送足夠的數據。 正確的帖子結構是:

file_data = { 'file': ('test.png', open('../some_file.png', 'rb'), 'image/png') }
requests.post("http://whatever.com/path", data = { 'extra_data': "blah blah blah" }, files = file_data)

上面的代碼從“some_file.png”讀取,但告訴服務器它叫做“test.png”。

希望有所幫助!

老問題! 但我一直在尋找解決這個問題的方法。 我在處理IHTTPSession輸入流時遇到問題。 當讀取它時,流會過早地變空,你必須返回更多。 這發生在我發送大於500k的application/octet-stream數據時(我沒有描述確切的數字)。

我的解決方案是打開IHTTPSession輸入流,並迭代讀取輸入流,直到它完全耗盡:

public Response post_upload(IHTTPSession session) {   
    System.out.println("received HTTP post with upload body...");  
    int streamLength = Integer.parseInt(session.getHeaders().get("content-length"));
    System.out.println("Content length is: " + streamLength);
    byte[] fileContent = new byte[streamLength];
    try {
        InputStream input = session.getInputStream();
        int bytesRead = 0;
        int iterations = 0;
        while (bytesRead < streamLength) {              
            int thisRead = input.read(fileContent, bytesRead, streamLength-bytesRead);                
            bytesRead += thisRead;
            iterations++;
        }
        System.out.println("Read " + bytesRead + " bytes in " + iterations + " iterations.");
    }
    catch (Exception e) {
        System.out.println("We have other problems...");
    }
    return newFixedLengthResponse(Response.Status.OK, "application/json", "[\"no prob\"]");
}

我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM