【问题标题】:How does one load a different html page from the same Express controller script?如何从同一个 Express 控制器脚本加载不同的 html 页面?
【发布时间】:2018-06-13 02:33:55
【问题描述】:

我想更改第一页(登录页面),在对其执行一些定义的操作后,第二个页面(管理仪表板)来自同一Express 中的控制器。

这是我来自nimda.js 的重要控制器代码:

function handlePut(req, res){
    let html = fs.readFileSync(path.join(__dirname,'../static/feed.html'));
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(html);
}

router.put('/', handlePut);

// This handles the form submitted.
router.post('/', function(req, res){
    if(req.body.pwd != '1234')
        res.send('False');
    else
        {
            //Doesn't work from here.
            handlePut(req, res);
        }
});

//This is when server.js routes the request to this script
router.get('/', function( req, res){
    let html = fs.readFileSync(path.join(__dirname,'../static/login_nimda.html'));
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(html);
});

我认为在身份验证后从我的 POST 代码中执行 PUT 可以帮助我发送一个新的 HTML 页面作为响应。第一个 HTML 页面是 login_nimda.html,它向 /nimda 发出 POST 请求。 这不起作用,我保持不变login_nimda.html。不过 POST 请求可以正常工作。

这是我login_nimda.html的脚本:

<script>
 $('#submit').on('click', function(){
        var form = $('#log').serialize();

        $.post('/nimda', form).done(function(data) {
                if(data=="False" && $('#err').length==0){
                    $('#log').prepend('<p id = "err" class = "alert alert-info" align = "centre" > Incorrect!</p>');
                }
                else
                {
                    $('#err').remove();
                    document.location.href = '/nimda/'+data;  
                }
        });
});
</script>

非常欢迎这种方法的任何替代方案。

【问题讨论】:

    标签: javascript jquery node.js ajax express


    【解决方案1】:

    好的,所以我可以想出两种完全不安全的方法-

    1.将密码作为方法信息传递身份验证后

    login_nimda.html下的脚本修改为向同一个控制器nimda.js发送请求:

    $.post('/nimda', form).done(function(data) {
        if (data == "False" && $('#err').length == 0) {
            $('#log').prepend('<p id = "err" class = "alert alert-info" align = "centre" > Incorrect!</p>');
        } else {
            $('#err').remove();
            document.location.href = '/nimda/'+$('input[type="password"]').val();  
        }
    });
    

    由于密码仅在验证成功后才会出现在 URL 中,因此只有授权用户才能看到它 - 缺点:带有 URL 的密码会被缓存

    nimda.js被修改为加载“第二页”:

    //the handler I added
    router.get('/your_password', function(req, res){
        let html = fs.readFileSync(path.join(__dirname,'../static/second_page.html'));
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(html);
    });
    
    //for login authentication
    router.post('/', function(req, res){
        if(req.body.pwd != '1234')
            res.send('False');
        else
            res.send('True');
    });
    

    2。在方法信息post authentication中向控制器传递一个随机字符串

    嗯,我目前没有更好的选择

    login_nimda.html 下的脚本被修改为向同一个控制器nimda.js 发送请求,但这一次,没有传递密码而是一个随机字符串接收到作为访问密钥的身份验证后

    <script>
     $('#submit').on('click', function(){
            var form = $('#log').serialize();
    
            $.post('/nimda', form).done(function(data) {
                    if(data=="False" && $('#err').length==0){
                        $('#log').prepend('<p id = "err" class = "alert alert-info" align = "centre" > Incorrect!</p>');
                    }
                    else
                    {
                        $('#err').remove();
                        document.location.href = '/nimda/'+data;  
                    }
            });
    });
    </script>
    

    nimda.js 被修改为添加一个新的路由处理程序仅在每次身份验证成功时使用路由 /nimda/new_random_string 并且密钥 (new_random_string) 作为响应传递,以便控制移动到新的处理程序以显示第二页:

    var key = '';
    
    function createRandomString( length ) {
        var str = "";
        for ( ; str.length < length; str += Math.random().toString( 36 ).substr( 2 ) );
        key = str.substr( 0, length );
        return key;
    }
    
    router.post('/', function(req, res){
        if(req.body.pwd != '1234')
            res.send('False');
        else
            {
                router.get('/'+ createRandomString(16), function(req, res){
                let html = fs.readFileSync(path.join(__dirname,'../static/feed.html'));
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.end(html);
                });
                res.send(key);
            }
    });
    

    这样键可以随着每个请求而改变,因此缓存变得无用。 请让我知道更好的解决方案。我知道有!

    【讨论】:

    • 为什么你认为第二种方式“不安全”? (当然是第一个)。
    • 我不知道我只是觉得它不安全。是吗?
    • 这个原理对我来说似乎很合理,它实际上类似于会话 cookie 的工作方式。
    【解决方案2】:

    当您使用 JavaScript 发送 POST 请求时,您处于浏览器(客户端)中。浏览器将收到对该请求的响应,作为文本数据,包含 HTML 或服务器发送的任何内容。

    如果作为对您在 JavaScript 中收到的数据的响应,您希望移动到另一个页面,则必须在 JavaScript 中执行此操作。

    在 JavaScript 中,您将使用 window.location:

    $.post('/nimda', form).done(function(data) {
        if (data == "False" && $('#err').length == 0) {
            $('#log').prepend('<p id = "err" class = "alert alert-info" align = "centre" > Incorrect!</p>');
        } else {
            $('#err').remove();
            document.location.href = '/some-page.html';  
        }
    });
    

    【讨论】:

    • 嗯,我不想暴露some-page.html的名字。我宁愿希望控件在 POST 方法中进行身份验证后移动到控制器内部,然后从那里发送第二个 HTML 文件。
    • 服务器无法强制浏览器加载其他资源。如果您不想公开您的重定向页面,请重定向到/whatever.html,然后让服务器提供您想要的页面或重定向到另一个页面。无论哪种方式,一旦页面加载,您就无法阻止用户知道 URL。
    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2013-04-20
    相关资源
    最近更新 更多