nginx反向代理Angular Node应用混合内容http请求

cl25kdpy  于 2023-04-29  发布在  Nginx
关注(0)|答案(3)|浏览(170)

我正在处理nginx和node express服务器,该应用程序用于通过端口80的反向代理工作正常,但当我在nginx上安装SSL与certbot时开始出现问题,我一直在尝试https节点模块,但当我从我的Angular 前端向我的节点后端发出请求时,我仍然会收到混合内容错误。我认为这是一个糟糕的流量配置在nginx,也许我需要设置流量从nginx到节点服务器(端口3000)与http,但我不知道如何实现这一点。先谢谢你了。
请求时出现控制台错误:
polyfills-es2015。aa82454585d558e1759e。js:1混合内容:页面在'https://www.example.com/signup'通过HTTPS加载,但请求了不安全的XMLHttpRequest端点' http://myVpsIpNumber:3000/api/register '。此请求已被阻止;内容必须通过HTTPS提供。
这是我的nginx:

server {

   server_name example.com www.example.com;

    location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name example.com www.example.com;
    return 404; # managed by Certbot

}

我的快递服务器:

const express = require('express');
const cors = require('cors');

let app = express();

//routes
const user_routes = require('./routes/user.router');

// middlewares
app.use(cors());

app.use(('/'), express.static('client', {redirect: false}));
app.use('/api', user_routes);

app.get('*', function(req, res, next){
    res.sendFile(path.resolve('client/index.html'));
})

// start server
app.listen(3000, () => console.log('Server started at port : 3000'));

Angular服务:

import { HttpClient, HttpHeaders } from '@angular/common/http';

noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True' }) };

constructor(private http: HttpClient) {}

  postUser(user: User){
    return this.http.post('http://localhost:3000/api' + '/register', user, this.noAuthHeader);
 }

节点后端:

register: (req, res, next) => {
        let user = new User();
        user.email = req.body.email;
        user.password = req.body.password;
    
        user.save((err, doc) => {
            if (!err)
                res.send(doc);
            else {
                if (err.code == 11000)
                    res.status(422).send(['Email ya registrado']);
                else
                    return next(err);
            }
        });
    }
stszievb

stszievb1#

问题出在前端的API调用中,解决方案是将URL替换为SSL域(使用https://)。
开发:

'http://localhost:3000'

生产:

'https://www.example.com'
import { HttpClient, HttpHeaders } from '@angular/common/http';

noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True' }) };

constructor(private http: HttpClient) {}

postUser(user: User){
  return this.http.post('https://www.example.com/api' + '/register', user, this.noAuthHeader);
}
vuktfyat

vuktfyat2#

我也遇到了同样的问题,虽然不是Angular,而是Vuejs。使用http一切正常,但在安装SSL证书与certbot后,我得到了“混合内容”错误。我是一个初学者,不知道如何让我的前端与后端对话。我花了很长时间来解决这个问题,希望这能有所帮助:
1.复制您的“dist”文件夹,您将在其中存储您的生产构建版本,并将其复制到/var/www/html目录中,如so $ cp -r /usr/src/app/dist/* /var/www/html
1.在/etc/nginx/sites-available/default的Nginx默认文件应该看起来像这样:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }
}

server {

    root /var/www/html;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;
    server_name www.example.com example.com; # managed by Certbot

    location / {
        try_files $uri $uri/ =404;
    }

location /api {
         proxy_pass http://localhost:3000; 
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80 ;
    listen [::]:80 ;
    server_name www.example.com example.com;
    return 404; # managed by Certbot
}

1.在前端使用https://example.com/api而不是http://localhost:3000/api,就像这样(不确定这在Angular中是否完全像这样工作,但你明白了):

postUser(user: User){
    return this.http.post('https://example.com/api' + '/register', user, this.noAuthHeader);
 }
  1. app.js文件看起来没问题。所以不需要改变。
kq4fsx7k

kq4fsx7k3#

如果你使用Docker容器来托管前端,请确保你的Docker容器拉取并使用最新的Docker镜像和apiUrl(e.例如,https://example.com/api)。

相关问题