javascript 从客户端请求使用 Node 运行 Bash 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16592851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 05:15:27  来源:igfitidea点击:

Run Bash Script with Node from client request

javascriptjquerynode.js

提问by Katie

I need to make a server-side script run when a user from the browser clicks a button...

当浏览器中的用户单击按钮时,我需要运行服务器端脚本...

I've been researching for a while, and can't figure it out.

研究了好久,还是搞不清楚。

What we have:

我们有什么:

  • Node.js server (on localhost) running on Fedora Red Hat
  • NO PHP
  • Most pages are html + javascript + jQuery
  • 在 Fedora Red Hat 上运行的 Node.js 服务器(在本地主机上)
  • 没有 PHP
  • 大多数页面是 html + javascript + jQuery

To be more clear, here is what we'd like to happen:

更清楚地说,这是我们希望发生的事情:

-->User goes to http:// localhost /index.html

--> 用户访问 http:// localhost /index.html

-->User selects colors, pushes "submit" button.

--> 用户选择颜色,按下“提交”按钮。

-->Selected colors go to the bash script (on the server) ./sendColors [listOfColors]

-->选定的颜色转到bash脚本(在服务器上)./sendColors [listOfColors]

-->The bash script does it's thing.

--> bash 脚本就是这样做的。

================

================

Things I've tried

我尝试过的事情

child_process.spawn

child_process.spawn

I WISH I could do this on the html page:

我希望我可以在 html 页面上做到这一点:

var spawn = require('child_process').spawn;
ls    = spawn(commandLine, [listOfColors]);

ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

ls.on('close', function (code) {
  console.log('child process exited with code ' + code);
});

but this script is server-side, not client-side, so I can't run it on the html page (I believe). The error I get when I try to run this is that require is undefined.

但是这个脚本是服务器端的,不是客户端的,所以我不能在 html 页面上运行它(我相信)。我尝试运行时遇到的错误是 require 未定义。

browserify

浏览器化

I've tried installinst browserify, but the machine we are using isn't connected to the internet, and cannot use npm install. I've manually copied over the files to usr/lib and "required" it fine, but then it said that it couldn't find require "through", which is in browserify's index.js...

我试过 installinst browserify,但我们使用的机器没有连接到互联网,无法使用 npm install。我已经手动将文件复制到 usr/lib 并“要求”它很好,但后来它说它找不到要求“通过”,这是在 browserify 的 index.js ...

getRuntime

获取运行时

tried this thing:

试过这个东西:

        var bash_exit_code = 0;          // global to provide exit code from bash shell invocation

        function bash(command)
        {
          var c;           // a character of the shell's stdout stream
          var retval = "";          // the return value is the stdout of the shell

          var rt = Runtime.getRuntime();        // get current runTime object
          var shell = rt.exec("bash -c '" + command + "'");   // start the shell
          var shellIn = shell.getInputStream();        // this captures the output from the command

          while ((c = shellIn.read()) != -1)        // loop to capture shell's stdout
            {
              retval += String.fromCharCode(c);        // one character at a time
            }

          bash_exit_code = shell.waitFor();        // wait for the shell to finish and get the return code

          shellIn.close();          // close the shell's output stream

          return retval;
        }

said it didn't know what Runtime was

说它不知道运行时是什么

RequireJS

要求JS

I've looked into RequireJS, but didn't understand how to use it in my case

我研究了 RequireJS,但不明白如何在我的情况下使用它

eval

评估

I've tried eval also... but I think that's for algebric expressions... didn't work.

我也试过 eval ......但我认为那是用于代数表达式......没有用。

ActiveX

ActiveX

even tried activeX:

甚至尝试过activeX:

variable=new ActiveXObject(...

said it didn't know what ActiveXObject is

说它不知道 ActiveXObject 是什么

================

================

Currently what I'm trying

目前我正在尝试什么

HttpServer.js:

HttpServer.js:

var http = require('http');
...
var colors = require('./colorsRequest.js').Request;
...

http.get('http://localhost/colorsRequest', function(req, res){
    // run your request.js script
    // when index.html makes the ajax call to www.yoursite.com/request, this runs
    // you can also require your request.js as a module (above) and call on that:
    res.send(colors.getList()); // try res.json() if getList() returns an object or array
    console.log("Got response ");// + res.statusCode);
    });

colorsRequest.js

颜色请求.js

var RequestClass = function() {
    console.log("HELLO");
}; 

// now expose with module.exports:
exports.Request = RequestClass;

index.html

索引.html

...
var colorsList = ...
...
$.get('http://localhost/colorsRequest', function(colors) {
            $('#response').html(colorsList); // show the list
    });

I'm getting

我越来越

GET http://localhost/colorsRequest 404 (Not Found)

Anyone got any ideas?

有人有任何想法吗?

回答by robertklep

Here's a simple boilerplate for the server (which uses Express, so you might need to install that first: npm install express):

这是服务器的一个简单样板(使用Express,因此您可能需要先安装它:)npm install express

var spawn   = require('child_process').spawn;
var express = require('express');
var app     = express();

app.use(express.static(__dirname));

app.get('/colorsRequest', function(req, res) {
  var command = spawn(__dirname + '/run.sh', [ req.query.color || '' ]);
  var output  = [];

  command.stdout.on('data', function(chunk) {
    output.push(chunk);
  }); 

  command.on('close', function(code) {
    if (code === 0)
      res.send(Buffer.concat(output));
    else
      res.send(500); // when the script fails, generate a Server Error HTTP response
  });
});

app.listen(3000);

You can pass it a color, and it will run the shellscript run.sh(of which it assumes is located in the same directory as the server JS file) with the color passed as argument:

你可以给它传递一个颜色,它会运行 shellscript run.sh(假设它与服务器 JS 文件位于同一目录中),并将颜色作为参数传递:

curl -i localhost:3000/colorsRequest?color=green
# this runs './run.sh green' on the server

Here's a boilerplate HTML page (save it as index.html, put it in the same directory as the server code and the shell script, start the server, and open http://localhost:3000in your browser):

这是一个样板 HTML 页面(另存为index.html,将其与服务器代码和 shell 脚本放在同一目录中,启动服务器,然后http://localhost:3000在浏览器中打开):

<!doctype html>
<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  </head>
  <body>
    <select>
      <optgroup label="Pick a color:">
        <option>green</option>
        <option>blue</option>
        <option>yellow</option>
        <option>orange</option>
      </optgroup>
    </select>
    <script>
      $('select').on('change', function() {
        $.get('/colorsRequest', { color : $(this).val() });
      });
    </script>
  </body>
</html>

回答by Eugen Rieck

You are on the right way with your first approach, the child_process.spawnvariant. Ofcourse you can't put this in the HTML page, as it is then executed in the browser, not in the server, but you can easily create a request in the browser (AJAX or page load, depending on what you need), that triggers running this script in the server.

您的第一种方法(child_process.spawn变体)走在正确的道路上。当然你不能把它放在 HTML 页面中,因为它是在浏览器中执行的,而不是在服务器中,但是你可以轻松地在浏览器中创建一个请求(AJAX 或页面加载,取决于你的需要),即触发在服务器中运行此脚本。