简体   繁体   English

Node.js和快速重定向到https不适用于主页

[英]Nodejs & express redirection to https not working for homepage

I'm using express to serve static files on my vps. 我正在使用express在我的vps上提供静态文件。 I created two servers http and https like so: 我创建了两个服务器httphttps如下所示:

var httpServer = http.createServer(app);
httpServer.listen(httpPort);

var httpsServer = https.createServer(credentials, app);
httpsServer.listen(httpsPort);

By using a middlewear like below: 通过使用如下所示的中间件:

app.use(function (req, res, next) { 
    !req.secure 
        ? res.redirect(301, path.join('https://', req.get('Host'), req.url)) 
        : next();
});

Most of my requests are well redirected to https. 我的大部分请求都很好地重定向到了https。 However, when loading my website with only the domain without ssl ( http://example.com ) and without any child routes (like http://example.com/contact ), this is not redirecting to https. 但是,当仅使用没有ssl的域( http://example.com )和没有任何子路由(例如http://example.com/contact )加载我的网站时,这不会重定向到https。

Edit 编辑

I serve static files (an angular 4 app compiled for production): 我提供静态文件(为生产而编译的angular 4应用程序):

app.use(express.static(path.join(__dirname, distFolder)));

And I have as route what follows: 我的路线如下:

app.get('*', (req, res) ={ 
    res.sendFile(path.join(__dirname, distFolder, 'index.html'));
});

Can you help me to find out what I missed ? 您能帮我找出我错过的内容吗? I didn't find answer for this exact issue. 我没有找到这个确切问题的答案。

Thank you. 谢谢。

We can also use node-rest-client for redirecting properly to any URL. 我们还可以使用node-rest-client正确地重定向到任何URL。

You can install it by npm install node-rest-client 您可以通过npm install node-rest-client

path.join is meant for joining together path elements, and should not be used to construct URLs. path.join用于将路径元素连接在一起,不应用于构造URL。 In your example the redirect url will be missing one of the leading slashes. 在您的示例中,重定向URL将缺少前导斜杠之一。

> path.join('https://', 'example.com', '/hello/world')
'https:/example.com/hello/world'

Instead you can use url.format , which will construct a proper url. 相反,您可以使用url.format ,它将构造一个适当的url。

> url.format({ protocol: 'https:', host: 'example.com', pathname: '/hello/world' })
'https://example.com/hello/world'

Your code would look something like this: 您的代码如下所示:

app.use(function (req, res, next) {
  if (req.secure) return next()

  const target = url.format({
    protocol: 'https:',
    host: req.get('Host'),
    pathname: req.url
  })

  res.redirect(301, target)
})

I finally found out what was the issue: I was serving the public folder before the security test... 我终于发现了问题所在:在安全测试之前 ,我正在提供公用文件夹...

So here are the steps now: 所以这是现在的步骤:

// Step 1: Test all incoming requests (from http and https servers).

app.use(function (req, res, next) {
    if (req.secure) 
        return next();

    var target = url.format({ // Thanks Linus for the advice!
        protocol: 'https:',
        host: req.hostname,
        pathname: req.url
    });

    res.redirect(301, target);
});

// Step 2: Serve static files.

app.use(express.static(path.join(__dirname, 'your/dist/folder')));

// Step 3: Build routes (in my case with * because of the SPA).

app.get('*', function (req, res) {
    res.sendFile(path.join(__dirname, 'your/dist/folder', 'index.html'));
});

Now it is working perfectly! 现在它运行良好!

我建议您尝试在Web服务器层而不是应用程序层上解决此问题,并通过80和443接收安全请求和非安全请求/流量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM