首页 > 解决方案 > 节点如何操作 HTML DOM - 找不到文档错误

问题描述

我有一个服务于各种不同 HTML 页面的 Node 服务器。在其中一个页面中有一个表格。单击表单时,节点 server.js 文件中的端点会使用表单数据。同一个 HTML 页面包含一个

提交表单时我想修改其文本内容的元素。我在网上看到了各种教程,展示了如何document.getElementById('predictionText').innerHTML = prediction;使用内联 javascript 动态设置文本的值。如何使用 Node 和外部 js 实现这一点?

下面是我的代码:

<!DOCTYPE html>

<html>

  <head>
    <link rel="stylesheet" type="text/css" href="css/styles.css">
  </head>

  <body class="bodyContent">
    <p>This is the predictor page -- it will hold a form for the user to input relevant data to.</p>
    <section class="active" id="navigationBarSection">
      <ul>
        <li><a href="index">Home</a></li>
        <li><a href="predictor">Predictor</a></li>
        <li><a href="how_it_works">How it Works</a></li>
        <li><a href="about_us">About Us</a></li>
      </ul>
    </section>

    <section id="predictorUserInputSection">
    <form action="/post_data_to_predictor_algorithm" method="POST" id="attributeInputForm">
      <input class="textInput" required name="averageAreaIncome" placeholder="Average Area Income" />
      <input class="textInput" required name="averageAreaNumberOfRooms" placeholder="Average Area Number of Rooms" />
      <input class="textInput" required name="averageAreaHouseAge" placeholder="Average Area House Age" />
      <input class="textInput" required name="averageAreaNumberOfBedrooms" placeholder="Average Area Number of Bedrooms"/>
      <input class="textInput" required name="areaPopulation" placeholder="Area Population"/>
      <button id="submitButton">Submit</button>
    </form>
  </section>

  <section id="predictionResultsSection">
    <p id="predictionText"><font size="6">here </p>
  </section>

  <script src="server.js"></script>
  </body>

</html>

应该更新文本的节点服务器:

//jshint esversion:8

//adding all required dependencies/packages
const express = require('express');
const path = require('path');
const fs = require("fs");
const bodyParser = require('body-parser'); //for parsing post requests
const request = require('request') //for making HTTP requests

//specifies that this app will be using express.
const app = express();

//middleware for processing POST requests a bit easier.
app.use(bodyParser.urlencoded({extended: false}));

//static AWS EC2 instance server port. Edit with caution.
const serverPort = 5001;

const FLASK_SERVER_LOCAL_ENDPOINT = "http://localhost:5000/predictPrice";

//Allow the use of static files in project directory
app.use('/js', express.static(__dirname + '/js'));
app.use('/html', express.static(__dirname + '/html'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/node_modules', express.static(__dirname + '/node_modules'));
app.use('/resources', express.static(__dirname + '/resources'));

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;


//Handle all root requests.
app.get("/", function(req, res) {
  res.sendFile(path.resolve("index.html"));
});

app.get("/index", function(req, res) {
  res.sendFile(path.resolve("index.html"));
});

app.get("/predictor", function(req, res) {
  res.sendFile(path.resolve("html/predictor.html"));
});

app.get("/how_it_works", function(req, res) {
  res.sendFile(path.resolve("html/how_it_works.html"));
});

app.get("/about_us", function(req, res) {
  res.sendFile(path.resolve("html/about_us.html"))
});


//HERE IS THE PROBLEM
app.post("/post_data_to_predictor_algorithm", (req, res) => {
  //update prediction label in the UI:
  console.log("Updating label!");
  document.getElementById('predictionText').innerHTML = "received user response!";
});

运行服务器时,提交表单时出现以下错误:

ReferenceError: document is not defined
    at app.post (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/server.js:90:3)
    at Layer.handle [as handle_request] (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/layer.js:95:5)
    at /Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/express/lib/router/index.js:275:10)
    at /Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/body-parser/lib/read.js:130:5
    at invokeCallback (/Users/vismarkjuarez/Documents/Github/RealEstatePriceEstimator/node_modules/raw-body/index.js:224:16)

标签: javascripthtmldom

解决方案


如果您想在表单的同一页面中更新 DOM 元素,您必须构建一个动态表单,因为带有 action="/destination" 的标准表单会将您发送到一个新页面,或者重建一个您无法在其中写入的现有页面文档导致节点不知道 DOM。您需要 Jquery 或直接使用 xhr。例如:

// Build a single field dynamic Form:

<div id="myForm">
  <input type="text" id="textA"></input>
  <button type="submit" onclick="getElements()"> Submit </button>
</div>


// The element that need be updated.

<section id="predictionResultsSection">
   <p id="predictionText"><font size="6">here </p>
</section>


// Get the "form" field value.

function getElements() {
    var tA = document.getElementById("textA");
    formSubmit(tA.value)
}


// Do the request 

function formSubmit(sendData) {

  var xhttp = new XMLHttpRequest();
  xhttp.open("POST", "http://localhost/post_data_to_predictor_algorithm");
  xhttp.send(sendData);

  // Receive the response from server on this.responseText var
  xhttp.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {

    document.getElementById('predictionText').innerHTML = this.responseText;

    }
  };

}


// Server side
app.post("/post_data_to_predictor_algorithm", (req, res) => {
  //do your logic and send the response

  res.send(yourResponse) // the onreadystatechange will hadle this on responseText

});

推荐阅读