【问题标题】:XmlHttpRequest status=0XmlHttpRequest 状态=0
【发布时间】:2013-01-18 12:32:24
【问题描述】:

我有一个来自 javascript 文件的 ajax 调用,我想将要删除的用户的 ID 作为参数传递:

function eliminaUtente(id,nome){
if (confirm("Sei sicuro di voler eliminare l'utente "
    + nome
    + "?")) {
var xmlHttp2 = new XMLHttpRequest();
xmlHttp2.open("POST", "EliminaUtente", true);
xmlHttp2.setRequestHeader("Content-type",
        "application/x-www-form-urlencoded");
var params2 = "id=" + id;
xmlHttp2.send(params2);
xmlHttp2.onreadystatechange = function() {
    if (xmlHttp2.readyState == 4) 
    {
                    alert(xmlHttp2.status);  <-----------this prints always 0!
        if (xmlHttp2.status == 200) //
        {
            alert("utente eliminato!");
        } else {
            alert("An error occurred while communicating with server.");
        }
    }
};

} }

在名为 EliminaUtente 的对应 Servlet 中,我有以下代码:

  protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    String id = request.getParameter("id");
    System.out.println(id);
    String query = "delete from utente where idutente=" + id;
    System.out.println(query);
    try {
        Class.forName("com.mysql.jdbc.Driver").newInstance();

        Connection con = DriverManager
                .getConnection("jdbc:mysql://localhost/Spinning?user=root");
        PreparedStatement prest = con.prepareStatement(query);
        prest.executeUpdate();

        response.setContentType("text/plain");
        PrintWriter ajaxWriter = response.getWriter();
        ajaxWriter.print("ok");
        ajaxWriter.flush();
        ajaxWriter.close();

        con.close();
    } catch (Exception e) {
        e.printStackTrace();
        response.setContentType("text/plain");
        PrintWriter ajaxWriter = response.getWriter();
        ajaxWriter.print("ko");
        ajaxWriter.flush();
        ajaxWriter.close();
    }

}

}

我不明白问题出在哪里……你能帮帮我吗? ;)

【问题讨论】:

  • Code 0 表示存在连接问题。
  • 是的,但我不明白在哪里!代码似乎正确...
  • 阅读准备好的语句。您真的不希望有人使用id=5 or 1=1 发布请求并删除您的所有用户。
  • @JBNizet 你是什么意思?
  • 任何人都可以使用id=5 or 1=1作为查询字符串向您的webapp发送请求,并且由于您盲目地将id连接到您的SQL查询,因此将执行以下查询:delete from utente where idutente=5 or 1=1,这将删除应用程序中的所有用户。这就是为什么应始终使用准备好的语句而不是字符串连接:download.oracle.com/javase/tutorial/jdbc/basics/prepared.html。我描述的是SQL注入攻击:en.wikipedia.org/wiki/SQL_injection

标签: java javascript ajax servlets xmlhttprequest


【解决方案1】:

错别字?

alert(xmlHttp2.status);

【讨论】:

  • 是的,对不起...我写问题时错了...但是它打印 0!
  • 但我认为您不必担心... xmlHttp2.readyState 从 0->4(未初始化、打开、发送、接收、加载) - 所以在 xmlHttp2.readyState= =4,你应该很高兴。 (不用担心 .status)
  • 这是评论,不是答案。
【解决方案2】:

问题是我必须在这一行输入 false:

xmlHttp2.open("POST", "EliminaUtente", FALSE);

【讨论】:

  • 可怕的想法。你真的不应该使用同步 ajax 请求,因为它们会阻塞 UI 线程,直到请求完成。如果您的应用需要这样做,您需要仔细查看您的设计并进行一些更改。
【解决方案3】:

我尝试了您的代码并进行了一些更改,我想解释一下我做了什么以及从中学到了什么。我阅读了一些资料。首先我阅读了XMLHttpRequest 对象和onreadyState 事件。 我实现了您的示例 PUTGET 操作方法。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <servlet>
        <servlet-name>testServlet</servlet-name>
        <servlet-class>com.test.testServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/test/*</url-pattern>
    </servlet-mapping>

</web-app>

testServlet.java

package com.test;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class testServlet extends HttpServlet {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        /*super.doPost(req, resp);*/
        String strId = req.getParameter("id");
        System.out.println(strId);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        //super.doGet(req, resp);
        String strId = req.getParameter("id");
        System.out.println(strId);
    }
}

和主要部分 NewFile.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <input type="button" value="Submit" onclick="eliminaUtente('1')" width="100%" />
</body>
<script language="javascript" type="text/javascript">
    function eliminaUtente(id) {

        var xmlHttp = new XMLHttpRequest();
        var url = "test/NewFile.jsp?id=" + id;
        xmlHttp.open("POST", url, true);
        xmlHttp.send(url);
        xmlHttp.onreadystatechange = function() {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                alert("utente eliminato!");
            } else {
                alert("An error occurred while communicating with server.");
            }
        };
    }
</script>
</html>

通过这种方式,我编写参数 1(我在 jsp 文件方法调用中对其进行硬编码)并将其写入控制台,这里的第一件事是您的代码和我的代码不同,我删除了 xmlHttp2.setRequestHeader("Content-type","application/x-www-form-urlencoded");,因为如果方法类型是POST 默认加密是这样的。

enctype = content-type [CI]
This attribute specifies the content type used to submit the form to the server (when the value of method is "post"). The default value for this attribute is "application/x-www-form-urlencoded". The value "multipart/form-data" should be used in combination with the INPUT element, type="file".
  • 因此,POST 无需编码默认值即可。
  • 这是开放的方法签名open(method, url, async, user, password)这里的async是参数,这意味着如果它是假的,不要等待来自服务器的响应,当响应到来时执行另一行它将运行。如果是真的,请等到响应到来。实际上我尝试了他们的机器人并且它有效。
  • 最后我尝试使用GET。如果您想将它与GET 一起使用,您应该添加xmlHttp2.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 代码进行加密并从send() 方法中删除url 参数。

    函数 eliminaUtente(id) {

        var xmlHttp = new XMLHttpRequest();
        var url = "test/NewFile.jsp?id=" + id;
        xmlHttp.open("GET", url, true);
            xmlHttp2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xmlHttp.send();
        xmlHttp.onreadystatechange = function() {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                alert("utente eliminato!");
            } else {
                alert("An error occurred while communicating with server.");
            }
        };
    } 
    

注意:我在 Firefox 中尝试此代码,我创建了 xmlHttpRequest 对象。对于所有浏览器(包括 IE6),请确保您知道使用:

var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2012-12-30
    相关资源
    最近更新 更多