提问者:小点点

表单用Ajax提交到节点后端


我是node的新手,我正在尝试做一个表单,通过Ajax提交和传递数据,并在node后端处理数据。 处理完数据后,应该将数据发回并显示在index.html上。 但是在发送回任何数据之前,我已经在将数据发送到节点后端时遇到了问题。

此任务有限制。 我被告知在不使用任何外部库(如express,request等)的情况下实现上述目标。

我相信server.js,index.js,router.js没有问题。 但为了清楚起见,我在下面显示了它。 问题可能出在ajax代码和函数convert{}中。 现在,我只是console.logging每个点的数据,以确保数据传递到node。

下面是我的代码,奇怪的是我不能弄清楚为什么它不能正常工作,我在这上面花了很多小时。

我在命令行中收到了来自请求处理程序文件中函数convert{}的消息“Hello World”。 看来Ajax工作得很好,至少在xhr.open上是这样。 但是console.log下面的代码(“hello world”); 未执行(Request.AddListener)。 然后它再次打开我的index.html文件,因为我的命令行显示执行了“/”处理程序。

非常感谢任何关于解决这个问题的建议。 谢谢!

index.html:

        <form method="post" id = "fform">
        <input type="checkbox" id="text1" name="number1" >
        <label for="text1"> Number 1</label><br />
        <input type="checkbox" id="text2" name="number2" >
        <label for="text2"> Number 2</label><br />
        <h4>Select a date</h4>
        <select id="text3" name="month">
            <option value="01">Jan</option>
            <option value="02">Feb</option>
            <option value="03">Mar</option>
            <option value="04">Apr</option>
            <option value="05">May</option>
            <option value="06">Jun</option>
            <option value="07">Jul</option>
            <option value="08">Aug</option>
            <option value="09">Sep</option>
            <option value="10">Oct</option>
            <option value="11">Nov</option>
            <option value="12">Dec</option>
        </select>
        <select id="text4" name="year">
            <option value="2009">2007</option>
            <option value="2009">2008</option>
            <option value="2009">2009</option>
            <option value="2009">2010</option>
            <option value="2009">2011</option>
            <option value="2009">2012</option>
            <option value="2009">2013</option>
            <option value="2009">2014</option>
            <option value="2009">2015</option>
            <option value="2009">2016</option>
        </select>
        <h4>Output Type</h4>
        <input type="checkbox" id="text5" name="table" >
            <label for="text5"> As a Table</label>
        <input type="checkbox" id="text6" name="graph" >
            <label for="text6">As a Graph</label><br /><br />
        <<button type="submit" onclick="return showData()" >Submit</button>

index.html脚本。 目前xhr.send是一个字符串,用于测试。

<script>
    function showData() {
        var xhr = new XMLHttpRequest();
        xhr.open("POST","./convert",true);
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.send("foo=bar&lorem=ipsum");
    }
</script>

index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {};
handle["/"] = requestHandlers.reqStart;
handle["/convert"] = requestHandlers.convert;

server.startServer(router.route, handle);

router.js

var url = require("url");

function route(pathname, handle, response, request) {
    console.log("Routing a request for: "+ pathname);

    if (typeof handle[pathname] === 'function') {
        handle[pathname](response, request);
    } else {
        console.log("Nothing found for: " + pathname);
        response.writeHead(404, {"Content-Type": "text/plain"});
        response.write("Resource cannot be found!");
        response.end();
    }
}
exports.route = route;

server.js

var http = require("http");
var url = require("url");

function startServer(route, handle) {
    function onRequest(request, response) {
        var pathname = url.parse(request.url).pathname;
        console.log("Requesting for " + pathname + " received.");   
        route(pathname, handle, response, request);
    }
    http.createServer(onRequest).listen(41075);
    console.log("Server is now started.");
}

exports.startServer = startServer;

RequestHandler.js

var qs = require("querystring");
var fs = require("fs");
var url = require("url");

function reqStart(response, request) {
 //processing goes here to open index.html, code hidden, no problem here
}

function convert(request, response) {

    console.log("Hello World");

    request.addListener('data', function(dataChunk) {
        console.log("Received POST chunk'"+dataChunk+"'.");
        request.addListener('end', function() {
            console.log("You've sent: " + dataChunk);
            response.end();
        });
    });
}

共2个答案

匿名用户

不建议使用内联事件处理程序,当然也不建议在提交按钮上使用内联事件处理程序

由于您没有取消click事件(通过在函数中返回false),您将尝试同时进行ajax和提交

这里有一个更好的方法

window.addEventListener("load",function() {
  document.getElementById("fform").addEventListener("submit",function(e) {
    e.preventDefault(); // stop submission
    let xhr = new XMLHttpRequest();
    xhr.open("POST","./convert",true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    xhr.send("foo=bar&lorem=ipsum");
  }) 
})

匿名用户

onclick="return showData()"

当您使用1990年代的方法添加事件侦听器时,从函数返回false将阻止默认行为(即常规提交表单)到action属性中指定的URL(如果没有action属性,则为当前URL)。

您将返回showdata的返回值。 此函数没有return语句,因此返回undefined

这并不妨碍常规的表单提交,因此在启动Ajax请求之后,表单提交并加载一个新页面(杀死运行JavaScript程序等待Ajax请求响应的页面)。

您需要返回false

现代方法是将事件侦听器与JavaScript绑定,并使用PreventDefault方法停止表单提交:

const form = document.querySelector("form");
form.addEventListener("submit", showData);

function showData(event) {
    event.preventDefault();
    const xhr = new XMLHttpRequest();
    xhr.open("POST", "./convert");
    const params = new URLSearchParams();
    params.append("foo", "bar");
    params.append("lorem", "ipsum");
    xhr.send(params);
}