【问题标题】:JavaScript sending XmlHttpRequest only works in Debug Console发送 XmlHttpRequest 的 JavaScript 仅适用于调试控制台
【发布时间】:2014-01-14 04:14:51
【问题描述】:

亲爱的社区,你好。

我有一个似乎无法解决的问题。 让我解释一下我想做什么。

我有一个带有选择文件对话框和提交按钮的简单 JSF 站点。 当用户选择一个文件并单击提交按钮时,该文件将被发送到我服务器上的一个 servlet,它保存在本地,并应创建一个指向该文件位置的 db 条目。 听起来很简单吧? 到目前为止,这是我的解决方案:

JavaScript:

function postUploadedFile() {
    var servlet = "UploadImageToServer";
    var inputElement = document.getElementById('filedataDecoded');
    var fileTypeElement = document.getElementById('filedataType');
    var encodedFile = inputElement.textContent;
    var fileType = fileTypeElement.textContent;
    inputElement.textContent = "";
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("POST", "http://localhost:8080/TestJSF/" + servlet + "?fileType="+fileType , true);
    xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlhttp.onreadystatechange = function () {
        if ((xmlhttp.readyState == 4)) {
              // handle callback
              console.log("done");
        }
     }
    xmlhttp.send(encodedFile);
    console.log();
}

我的 Servlet:

public class UploadImageToServer extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static Logger logger = Logger.getLogger(UploadImageToServer.class);

    private String dbUser = "xxxx";

    private String dbPw = "xxxx";

    public UploadImageToServer() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PreparedStatement stm = null;
        Connection con = null;
        InputStream fileDataStream = request.getInputStream();
        int fileContentLength = request.getContentLength();
        String fileType = (request.getParameter("fileType")).split("\\.")[1];
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        byte[] fileDataBytes64 = new byte[fileContentLength];
        byte[] bufferTemp = new byte[1024];
        int nRead;
        while ((nRead = fileDataStream.read(bufferTemp, 0, bufferTemp.length)) != -1) {
          buffer.write(bufferTemp, 0, nRead);
        }
        buffer.flush();
        String tempString = buffer.toString();
        String base64String = tempString.split("base64,")[1];
        System.out.println("test");
        Double newRandom = (double) -1;
        while(newRandom < 5000 || newRandom > 1000000) {
            newRandom = Math.random() * 10000;
        }
        String valueOf = String.valueOf((newRandom));
        String fileName = (valueOf.split("\\."))[0] + "." + fileType;
        File tempFile = new File("C:\\storage\\" + fileName);
        byte[] fileDataDecoded = Base64.decodeBase64(base64String);
        tempFile.getParentFile().mkdir();
        tempFile.createNewFile();
        FileOutputStream foS = new FileOutputStream(tempFile);
        foS.write(fileDataDecoded);
        foS.close();
        String driver = PossibleDbDriver.MYSQL.getIdentifier();
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e2) {
            logger.error("Error - no valid Driver-Class specified - [" + driver + "]");
            logger.error("Message - [" + e2.getMessage() + "]");
        }
        String dbURL = "jdbc:mysql://localhost:3306/imagetest";
        try {
            con = (Connection) DriverManager.getConnection(dbURL,dbUser,dbPw);
            stm = con.prepareStatement("INSERT INTO images (image_name,image_path,image_likes,image_dislikes,image_timestamp) VALUES(?,?,?,?,?)");
            stm.setString(1, tempFile.getName());
            stm.setString(2, tempFile.getPath());
            stm.setDouble(3, 0);
            stm.setDouble(4, 0);
            stm.setTimestamp(5, new Timestamp(GregorianCalendar.getInstance().getTimeInMillis()));
            stm.execute();
         } catch (SQLException e) {
                logger.error("Error - Connection could not be established.");
                logger.error("Message - [" + e.getMessage() + "]");
         } 
    }
}

Servlet 映射:

  <servlet>
    <description></description>
    <display-name>UploadImageToServer</display-name>
    <servlet-name>UploadImageToServer</servlet-name>
    <servlet-class>mk.imageboard.servlets.UploadImageToServer</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadImageToServer</servlet-name>
    <url-pattern>/UploadImageToServer</url-pattern>
  </servlet-mapping>

文件数据来自另一个脚本,该脚本将其读取为 Base64-String 并将其写入 TextArea-Element 'filedataDecoded'(只是为了澄清这一点)。 应用服务器是 Tomcat 6.0.36,JSF 实现是 MyFaces 2.1.13。 一切都在同一台机器(我的电脑)上运行。

现在我的实际问题... 当我让 Tomcat 在正常模式下运行并访问我的站点并尝试上传文件时,XmlHttpRequest 不会发送。但是,当我在 Chrome 中打开 JavaScript 控制台并设置断点时:

            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("POST", "http://localhost:8080/TestJSF/" + servlet + "?fileType="+fileType , true);
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlhttp.onreadystatechange = function () {
                if ((xmlhttp.readyState == 4)) {
                      // handle callback
                      console.log("done");
                }
             }
            xmlhttp.send(encodedFile);

并单步执行脚本,发送请求并且 servlet 工作正常。 我在stackoverflow中搜索了一个解决方案,但找不到任何解决方案。与互联网相同。这是一个奇怪的错误,我不明白为什么它不起作用。 如果有人可以帮助我,我将不胜感激。

提前致谢

克里斯

【问题讨论】:

  • 您尝试过其他浏览器吗?
  • 是的。我也试过火狐。同样的问题。在设置了断点的调试控制台中它可以工作,没有和没有控制台它都不会。 (我忽略了 IE)
  • 那么,事情很严重!
  • 我想知道读取文件是否存在某种异步方面?尝试将 postUploadedFile 方法的主体包装在 try-catch 块中,然后将生成的错误对象记录到 console.error(...)
  • 我将我的代码包含在一个 try-catch 块中,但没有引发错误。我还在 console.log(error) 行设置了一个断点,但它没有被调用。我认为读取文件没有问题。当我按下提交按钮时,数据就出现了。通过填充文本区域元素的另一个按钮读取数据。所以postUploadFileonly 访问所有已经存在的数据。

标签: java javascript jsf tomcat servlets


【解决方案1】:

好的。我想我已经找到了解决方案或问题的原因。

不知何故,围绕触发 javascript 的实际提交按钮的&lt;h:form&gt;...&lt;/h:form&gt; 阻止了请求的发送,但至于为什么会这样,我不知道。我删除了表单,它现在可以正常工作了。

有人猜到为什么会导致问题吗?我真的很想知道。

不过还是谢谢各位。新年快乐:)

致以诚挚的问候

克里斯

编辑:我的网站缺少的 HTML 片段。对不起,我应该添加它,我的错!

<ui:define name="content">
        <!-- Testbereich -->
            <fieldset>
                <input type="file" id="file" name="file" enctype="multipart/form-data" onchange=""/>
                <input type="submit" value="Verschluesseln" onclick="loadUploadedFile();"/>
            </fieldset>
            <fieldset>
                <div> Uploaddaten nicht verschluesselt:</div>
                <h:inputTextarea id="filedataType" styleClass="textareaOutput" disabled="true"/>
                <h:inputTextarea id="filedataDecoded" styleClass="textareaOutput" disabled="true"/>
            </fieldset>
            <!-- <h:form id="uploadForm"> -->
                <fieldset>
                    <input type="submit" onclick="postUploadedFile();"/>
                </fieldset>
            <!-- </h:form> -->
    </ui:define>

澄清loadUploadedFile()是读取文件并返回Base64字符串的javascript。

【讨论】:

  • 请添加 HTML 以便我们查看。我猜您正在使用带有 onclick 的 HTML 提交按钮?如果是这种情况,提交按钮将提交表单,这可能没有足够的时间从 onclick 事件中运行您的 JS。您可以尝试将提交更改为
  • 谢谢@pherris 我认为这是合乎逻辑的原因。事实上,页面重新加载,我自己也猜到了。 :(
【解决方案2】:

尝试使用相对路径而不是绝对路径。

xmlhttp.open("POST", "TestJSF/" + servlet + "?fileType="+fileType , true);

xmlhttp.open("POST", "" + servlet + "?fileType="+fileType , true);

更新:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doPost(request,response);
    }

xmlhttp.open("GET", "TestJSF/" + servlet + "?fileType="+fileType , true);

xmlhttp.open("GET", "" + servlet + "?fileType="+fileType , true);

【讨论】:

  • 遗憾的是这不起作用。似乎无法以这种方式访问​​ servlet。应该是吗?我错过了什么吗?
  • 你需要知道你在哪个路径上工作。它可能是“/TestJSF/”或“/”。这与你的工作路径有关。并确保您的参数值是真实的。
  • 遗憾的是仍然无法正常工作:xmlhttp.open("POST", "/TestJSF/" + servlet + "?fileType="+fileType , true); 工作但仍仅在调试控制台中。使用 GET -> 重定向到 post-method 的方法不起作用(即使使用调试控制台也不行)。参数值已设置,或者您所说的“并确保您的参数值是真实的”是什么意思。
猜你喜欢
  • 2018-12-15
  • 2021-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 2020-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多