【问题标题】:How to call a node js function from a separate front end javascript function如何从单独的前端 javascript 函数调用节点 js 函数
【发布时间】:2021-03-05 03:31:58
【问题描述】:

我有一个 node js 后端 (app.js),它连接到一个 html、css 和 javascript (script.js) 前端。

在我的 HTML 中,我有一个获取图像的表单,然后调用 script.js 中的函数。

Script.js 然后使用 ajax 和 jquery 上传文件,效果很好。

一旦完成,我希望它自动调用我在 app.js 中的一个函数,该函数调用一个 python 脚本。

这个函数可以自己运行,但是我在连接文件上传和 python 脚本时遇到了问题。现在,当我上传显示该应用程序未定义的图像时,我收到一个错误。如何在一个函数中同时调用这两个函数?

相关 HTML:

<form id="form">
     Select your image: <input type="file"  name="myfile" id="myfile" accept="image/x-png,image/jpeg"><br/>
     <input type="submit" value="Submit" class="getCodeButton"/>
 </form>
<div id="status"></div>

相关节点js(app.js):

const express = require('express')
    const bodyParser = require('body-parser')
    const multer  = require('multer')
    const sharp = require('sharp')
    
    const app = express()
    app.use(bodyParser.urlencoded({ extended: false })); 
    app.use(bodyParser.json());
    
    app.use(express.static('./public')) 
    app.use(express.static('./uploads/'))
    
    app.get('/', (req, res)=>{
        res.sendFile("index.html", { root: __dirname + "/public" })
    })
    
    const port = process.env.PORT || 8000
    app.listen(port, 
        ()=>console.log(`Server running on port ${port}`))
        
    const upload = multer().single('myfile')
    app.post('/upload', (req, res)=>{
        upload(req, res, async function(err){ 
         if( err|| req.file === undefined){
             console.log(err)
             res.send("error occured")
         }else{
            let fileName = "myfile.jpeg"
            var image = await sharp(req.file.buffer)
            .jpeg({
                quality: 40,
            }).toFile('./uploads/'+fileName)
            .catch( err => { console.log('error: ', err) })
            res.send(req.body)
         }
        })
    })
app.get('/runPython1', (req, res) => {
 
    var dataToSend;
    const python = spawn('python', ['qr_vision.py', 'uploads/myfile.jpeg']);
    python.stdout.on('data', function (data) {
    console.log('Pipe data from python script ...');
    dataToSend = data.toString();
    });
    python.on('close', (code) => {
    console.log(`child process close all stdio with code ${code}`);
    //console.log(dataToSend)
    res.send(dataToSend)
    });
 
})

相关的javascript(script.js):

document.getElementById('form').onsubmit = function(event){
    event.preventDefault()
    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("status").innerHTML = 'sent'+this.responseText+ xhttp.status;
      }else{
        document.getElementById("status").innerHTML = xhttp.status ;
      }
    }

    xhttp.open("POST", "upload")
    var formData = new FormData()
    formData.append('myfile', document.getElementById('myfile').files[0])
    xhttp.send(formData)
    
    app.get('/runPython1', (req, res) => {
        console.log(res.result)
    });
}

【问题讨论】:

  • “在一个函数中调用这两个函数”是什么意思? 哪里app是未定义的?如果你想在文件上传后运行 Python shell,为什么它在一个单独的函数中?不相关,但如果这意味着一次多人使用,文件命名就会出现问题。
  • 客户端,你不想要app.get('/runPython1') - 那是服务器端代码。相反,您需要对/runPython1 进行Ajax 调用并从服务器返回结果。您可以使用浏览器中的fetch() 接口进行Ajax 调用。
  • 我希望能够一个接一个地上传然后运行脚本。它说应用程序在浏览器控制台中未定义。我为模糊的措辞道歉。目前,我只在本地运行,没有针对多个用户的计划,但我会在扩展时牢记这一点!谢谢!
  • 客户端对除了端点之外的服务器端代码一无所知;您将向后端端点发出 request,就像您向后端端点发出第一个请求一样。

标签: javascript jquery node.js ajax


【解决方案1】:

您可以通过多种方式做到这一点

  1. 从前端:编写另一个 XMLHttpRequest 来调用 runPython1 端点,并在上传完成后发送请求。
  2. 从 nodejs 后端:您可以将 runPython1 作为函数并在上传完成后调用它,而不是将 runPython1 公开为 api 端点。
app.post('/upload', (req, res)=>{
        upload(req, res, async function(err){ 
         if( err|| req.file === undefined){
             console.log(err)
             res.send("error occured")
         }else{
            let fileName = "myfile.jpeg"
            var image = await sharp(req.file.buffer)
            .jpeg({
                quality: 40,
            }).toFile('./uploads/'+fileName)
            .catch( err => { console.log('error: ', err) })
            runPython1(res);
         }
        })
    })

const runPython1 = (res) => {
 
    var dataToSend;
    const python = spawn('python', ['qr_vision.py', 'uploads/myfile.jpeg']);
    python.stdout.on('data', function (data) {
    console.log('Pipe data from python script ...');
    dataToSend = data.toString();
    });
    python.on('close', (code) => {
    console.log(`child process close all stdio with code ${code}`);
    //console.log(dataToSend)
    res.send(dataToSend)
    });
 
}
  1. 上传完成后,您还可以重定向到 runPython1 端点。请参考This site 进行重定向

【讨论】:

  • 对于您的第二种方式,我将如何将其设为函数并调用它?
  • 我无法在评论中发布冗长的消息,所以我自己编辑答案
猜你喜欢
  • 2017-08-27
  • 1970-01-01
  • 2018-07-07
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
相关资源
最近更新 更多