【问题标题】:Want web page (js) file upload without form submission with servlet想要网页(js)文件上传而无需使用servlet提交表单
【发布时间】:2023-02-19 00:24:48
【问题描述】:

我正在尝试编写一个网页,允许在不提交表单的情况下将一个或多个文件上传到 servlet。

我愿意使用 jQuery 和/或 Ajax;我不想使用其他第三方库。

我有一个用于表单提交的 servlet;如有必要,我可以对其进行更改,使其在不提交表单的情况下工作:

package ajaxdemo;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
/* The Java file upload Servlet example */

@WebServlet(name = "FileUploadServlet", urlPatterns = { "/fileuploadservlet" })
@MultipartConfig
(
  fileSizeThreshold = 1024 * 1024 * 1, // 1 MB
  maxFileSize = 1024 * 1024 * 10,      // 10 MB
  maxRequestSize = 1024 * 1024 * 100   // 100 MB
)
public class FileUploadServlet extends HttpServlet 
{
  private static final long serialVersionUID = 1L;

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
  {
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Request-Method", "POST");

    /* Receive file uploaded to the Servlet from the HTML5 form */
    System.out.println("FileUploadServlet.doPost() invoked");
    Part filePart = request.getPart("file");
    String fileName = filePart.getSubmittedFileName();
    for (Part part : request.getParts()) 
    {
      part.write("C:\\tmp\\" + fileName);
    }
    response.getWriter().print("The file uploaded sucessfully.");
    response.getWriter().print("Filename: " + fileName + " saved in //tmp");
  }

}

这适用于以下输入表单:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="ISO-8859-1">
        <title>File Upload Form</title>
    </head>
    <body>
        <h3>File Upload:</h3>
        Select a file to upload: <br />
        <form action = "UploadFile.jsp" method = "post"
                enctype = "multipart/form-data">
                <input type = "file" name = "file" size = "50" />
                <br />
                <input type = "submit" value = "Upload File" />
        </form>
    </body>
</html>

为了在没有提交表单的情况下使其工作,我有以下页面:

<html>
<head>
<!-- after https://www.w3schools.com/howto/howto_css_modals.asp -->

<style>

body{font-family: Arial, Helvetica, sans-serif; }

/* file Upload dialog (from w3schools howto_css_modals) */
.fileUploadDialogClass
{
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* "Modal Content" (from w3schools howto_css_modals) */
.fileUploadDialogClassContentClass
{
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

/* "The Close Button" (from w3schools howto_css_modals) */
.fileUploadDialogCloseButtonClass
{
  color: #aaaaaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

/* (from w3schools howto_css_modals) */
.fileUploadDialogCloseButtonClass:hover,
.fileUploadDialogCloseButtonClass:focus
{
  color: #000;
  text-decoration: none;
  cursor: pointer;
}

    #upperLeft { background-color: lightgreen; border: 3px solid; }
    #licenseeCityState {background-color: lightblue; }
    #buttonDiv button { width: 100%; }
    #mainTable { width: 100%; }
    #mainTable { border: 1px solid;  }

</style>
</head>
<body>
  <script src="http://code.jquery.com/jquery-3.6.0.js"></script>

  <!-- file upload popup dialog -->
  <div id="fileUploadDialog" class="fileUploadDialogClass">
    <div class="fileUploadDialogClassContentClass">
        <span class="fileUploadDialogCloseButtonClass">&times;</span> <!-- 'times' is an 'x' for urh corner -->
        <P>Select a file, then upload it to be read</P>
        <br><input type="file" id="fileUploadChooserButton">
        <br><button id="fileUploadButton">Upload</button>
    </div>
  </div>
  
  <table>
  <tr>
    <td>
        <div id='buttonDiv'>
            <table id='buttonTable'>
                <tr><td><button id='openButton'>Open File</button></td></tr>
                <tr><td><button id='closeButton'>Close</button></td></tr>
            </table>
        </div>
    </td>
    <td style="vertical-align: top">
        <div id='lowerRight'>
            <table id='mainTable'>
                <tr><td><div id="idString">xxx</div></td></tr>
            </table>
        </div>
    </td>
  </tr>
  </table>

  <script>
  document.getElementById("idString").innerText = "xyz2";   // used to keep track of which version is displayed.
  var fileUploadDialog                  = document.getElementById("fileUploadDialog");
  var fileUploadDialogDisplayButton     = document.getElementById("openButton");
  var fileUploadDialogCloseButton       = document.getElementsByClassName("fileUploadDialogCloseButtonClass")[0];
  var fileUploadButton                  = document.getElementById("fileUploadButton");
  //fileUploadButton.onclick                = uploadFile();
  
  fileUploadDialogDisplayButton.onclick = function() { fileUploadDialog.style.display = "block"; }
  fileUploadDialogCloseButton.onclick = function() { fileUploadDialog.style.display = "none"; }
  
  //async function uploadFile()
  fileUploadButton.onclick = function()
  {
      console.log("uploadFile() invoked");
      let formData = new FormData();
      
      var fileUploadChooserButton = document.getElementById("fileUploadChooserButton");
      var files = fileUploadChooserButton.files;
      formData.append(files.name, files[0], files[0].name || "no filename")
      ;
      console.log("about to await fetch");
      // await fetch('http://localhost:8080/AjaxWithJSP/fileuploadservlet', { method: "POST", body: formData });
      
      const xmlRequest = new XMLHttpRequest();
      xmlRequest.onload = () => 
      {
              alert(xmlRequest.status + " reported as onload status");
      };
      //http://localhost:8080/AjaxWithJSP/LittleTable.html
      xmlRequest.open('POST', 'http://localhost:8080/AjaxWithJSP/fileuploadservlet', true);
      xmlRequest.setRequestHeader("Content-type", "multipart/form-data");
      xmlRequest.send(formData);
  }
  
  window.onclick = function(event) { if(event.target == fileUploadDialog) { fileUploadDialog.style.display = "none"; } }
  
  </script>

</body>
</html>

这会从服务器(在 eclipse 控制台中)产生一条错误消息,指出未找到多部分边界。

如果我注释掉设置请求标头的 JavaScript 行,错误消息是 filePart 为空,因此无法调用 getSubmittedFileName()

我发现另一种解释涉及await fetch(...)而不是xmlRequest.send(...);我上面已经注释掉了。我也无法让它发挥作用。

最后,我想允许用户上传多个文件,并返回一个 JSON 结构,我将用它来显示一个表格。但是我还没有弄清楚如何上传第一个文件。

【问题讨论】:

    标签: javascript ajax servlets file-upload


    【解决方案1】:
    xmlRequest.setRequestHeader("Content-type", "multipart/form-data");
    

    multipart/form-data 有一个强制参数,用于描述出现在每个多个部分之间的边界。

    在正常情况下,xhrfetch将生成整个Content-Type标头,包括来自FormData对象的boundary参数。

    在这里,您已经覆盖了 Content-type 并将其设置为 multipart/form-data没有一个边界。

    只是不要那样做。

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 2013-04-11
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 2023-01-05
      相关资源
      最近更新 更多