【问题标题】:Hosting Ionic 3 & expressJS RestAPI on same Docker Server在同一 Docker 服务器上托管 Ionic 3 和 express JS Rest API
【发布时间】:2020-05-04 01:22:10
【问题描述】:

我正在尝试在服务器上托管 Ionic 3 应用程序。该应用程序在 iOS、Android 和 localhost (ionic serve) 上正常运行,但一旦托管它就无法运行,我要疯狂地解决这个问题,因为没有错误!

服务器是一个数字海洋水滴。在它上面,我已经挂载了一个 Docker-compose 环境,因为我需要在同一台机器上放置多个 RestAPI+frontend

目前在 docker-compose 上有以下相关服务(+其他对问题没有用处):

  • ELK 堆栈的 Nginx 代理:只关心特定端口并在 Kibana 上重定向之前询问用户和密码[按预期工作]
  • 新容器的 Nginx 自动反向代理:每个新(前端)容器都将在子域后面代理 [按预期工作]
  • ExpressJS RestAPI(非代理):已经解决了 CORS 和其他小问题[按预期工作]
  • Ionic 前端容器:有问题的容器

问题似乎是 Ionic 容器无法接收 API 请求的所有标头。在 login 请求期间,服务器向我发回一个 Authorization 和一个 refreshToken 标头,我需要它们来进行进一步的请求!

我会附上一些图片来更好地解释我的意思:

预期行为(发生在本地主机上)

来自 Chrome 的 XHR POST

Ionic 的控制台日志

奇怪的行为(发生在托管的 ionic 上)

XHR(前导请求)

来自 Chrome 的 XHR POST

来自托管 Ionic 的控制台日志

为什么来自 hosts-ionic 的 console.log 没有接收/显示我想要的标头?

请求的IONIC CODE(函数->请求)

  • login.ts

    local_login(){
        console.log('dati inviati = user: ',this.user);
    
        this.req.local_login(this.user).then(data => {
          this.spinnerDialog.hide();
          if(data['status'] == 200){
            console.log('Ok => HomePage')
            this.goToPage("HomePage")
          }
          else {
            console.log('Login fallito => LoginPage')
            this.goToPage("LoginPage")
          }
        });
    
      }
    
  • request.ts

    local_login(body) {
        return new Promise(resolve => {
            let headers = new Headers();
            headers.append('Content-Type', 'application/json');
            headers.append('Authorization', this.commonVar.jwt);// EMPTY var
            headers.append('refreshToken', this.commonVar.rjwt);// EMPTY var
            this.http.post(this.site+':'+this.port+'/api/'+this._v+'/auth/local/login', body, {headers: headers})
            .subscribe((data) => {
              console.log('data >>>',data);
    
              data['_body'] = JSON.parse(data['_body']);
              if(data['status'] === 200){
                this.commonVar.jwt = data.headers.get('Authorization');
                console.log('Local >>>',data.headers.get('Authorization'))
                console.log('Storage >>>',this.commonVar.jwt)
    
                this.commonVar.rjwt = data.headers.get('refreshToken');
                console.log('Local >>>',data.headers.get('refreshToken'))
                console.log('Storage >>>',this.commonVar.rjwt)
    
                this.commonVar.user = JSON.stringify(data['_body']['data']);
                console.log('USER by Login =>',this.commonVar.user);
                console.log('login OK');
              }
              else {
                //TODO: handling error login
              }
              resolve(data);
            },error => {
              //TODO: handling error login
              console.error(error);
            });
        });
      }
    

如您所见,data(响应)的控制台日志仅在本地主机上完成。但是从 chrome xhr 我可以看到所有的标题。此外,单个标头的控制台日志不起作用(null)。

似乎代码没有在console.log 之前等待,但这是不可能的。我也尝试了 HTTP 模块的承诺形式,但没有成功。

也许问题与 Docker 有关?

我尝试通过以下方式执行 Ionic 容器:

  • 通过专用或共享 nginx 实例为 www 文件夹提供服务。
  • 以与上述相同的方式为平台/浏览器/www 提供服务。
  • 使用各种标志组合执行 ionic serve

所有这些方法都会重现同样的问题。

最初,我通过 indexedDB 使用localStorage,我认为这是问题所在。所以我也尝试删除它(你可以看到我如何使用共享变量)但问题仍然存在。

如果我忘记了什么,请询问。

感谢任何人都可以指出我正确的方向!

【问题讨论】:

    标签: angular docker nginx ionic-framework ionic3


    【解决方案1】:

    感谢answer,我被指出了正确的方向。

    问题本身不是离子问题,而是与 Rest 服务器的 CORS 配置有关。我为传入连接配置了有关标头所需的所有内容,但我忘记为传出连接配置它。

    以防万一有人遇到同样的问题:

    这是我之前在 ExpressJS 上关于 CORS 的配置:

    const express = require('express');
    var app = express();
    
    [...]
    
    var allowCrossDomain = function (req, res, next) {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
      res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization,refreshToken');
      next();
    };
    
    [...]
    
    app.use(allowCrossDomain);
    

    修正后:

    const express = require('express');
    var app = express();
    
    [...]
    
    var allowCrossDomain = function (req, res, next) {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
      res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization,refreshToken');
      res.header('Access-Control-Expose-Headers', 'Content-Type,Authorization,refreshToken');
      /* ^^^ This was the needed line! ^^^         ^^^ here you put your custom headers ^^^ */
      next();
    };
    
    [...]
    
    app.use(allowCrossDomain);
    

    希望这可以帮助其他人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 2015-10-15
      相关资源
      最近更新 更多