我有一个平均堆栈应用程序。在后端,我有api.js
:
var express = require('express')
var router = express.Router();
var body = 'response.send("hello fixed")';
var F = new Function ("request", "response", body);
router.get('/api/special', F);
module.exports = router;
因此,https://localhost:3000/api/special
会在浏览器中返回hello fixed
。
现在,我想让前端定义body
的内容。例如,我可以在网页上创建一个textarea,用户可以在那里输入例如response.send("hello flexible")
。然后,我需要将此内容传递给nodejs,以便https://localhost:3000/api/special
现在返回hello flexible
。
有谁知道如何实现这个目标?
编辑1:根据Andrew Li的评论,我修改了api.js
:
var express = require('express')
var router = express.Router();
router.put('/endpoint', function (req, res, next) {
console.log("api.js router.put /endpoint");
router.get('/api/special', eval('(' + req.body.value + ')'))
})
module.exports = router;
在控制器中:
app.controller('EndpointCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.body = 'function (request, response) { response.send("Hello") }';
$scope.changeBody = function (body) {
return $http.put('/endpoint', { value: body })
}
}])
奇怪的是,它仅在我第一次put /endpoint
时有效,而后来put
似乎没有更新/api/special
。有谁知道为什么?
此外,需要几秒钟才能看到后端控制台中的第二个或第三个put /endpoint
,这是有线的。
答案 0 :(得分:0)
为了扩展我的评论,这里有一个与你的例子相同的解决方案,但是使用一个调用变量的中间件。
const express = require( "express" );
const app = express();
function rawBody( req, res, next ) {
req.setEncoding( "utf8" );
req.body = "";
req.on( "data", chunk => req.body += chunk );
req.on( "end", next );
}
app.use( rawBody );
const router = express.Router();
// f is our variable; we initialize it to just call next, likely resulting in a 404
let f = ( req, res, next ) => next();
// use an intermediary function to invoke f
// don't use just f, which is passed by value and wouldn't update
router.get( "/api/special", ( ...args ) => f( ...args ) );
router.put( "/endpoint", ( req, res ) => {
// update f
f = eval( "(" + req.body + ")" );
// send a response; otherwise the request will hang
res.sendStatus( 200 );
} );
app.use( router );
app.listen( 3000 );
spread operator (...)以两种方式工作:将函数参数集合到数组中或将数组扩展为参数。这是Node LTS或更高版本的有效语法。您还可以明确使用( req, res )
。
我必须强调这样的端点非常容易受到攻击,因为它可以使用require,它可以从中执行任何进程有权执行的操作(例如下载和安装软件)。 vm2是一个可能有帮助的npm模块,但它们没有提供实际的安全保证。我建议您在沙箱中执行代码,并仅授予沙箱有限的权限(例如无法访问文件系统或网络)。