我在将angular / node / express应用程序部署到Heroku时遇到问题。此应用程序的首页上有一个用户名,然后将其路由到服务器以检索Google日历中即将发生的事件。
我可以毫无问题地在本地运行此应用程序。但是,当我部署到Heroku时,我在尝试获取日历信息时收到错误消息:
core.js:14597 ERROR DOMException: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
at https://my-app.herokuapp.com/newcal-angular/polyfills.js:5329:31
at XMLHttpRequest.proto.<computed> [as open] (https://my-app.herokuapp.com/newcal-angular/polyfills.js:3739:24)
at Observable._subscribe (https://my-app.herokuapp.com/newcal-angular/vendor.js:31301:17)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (https://my-app.herokuapp.com/newcal-angular/vendor.js:149418:25)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (https://my-app.herokuapp.com/newcal-angular/vendor.js:149404:22)
at https://my-app.herokuapp.com/newcal-angular/vendor.js:160669:31
at subscribeToResult (https://my-app.herokuapp.com/newcal-angular/vendor.js:160846:84)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub (https://my-app.herokuapp.com/newcal-angular/vendor.js:155603:90)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (https://my-app.herokuapp.com/newcal-angular/vendor.js:155597:14)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (https://my-app.herokuapp.com/newcal-angular/vendor.js:155580:18)
我知道此错误通常与格式不正确的API端点URL有关,但我不确定端点如何错/我应该如何正确设置它。过去问题的答案对这个问题没有帮助。我以为这可能与我在API调用中对“本地主机”的引用有关,但是我不确定一旦部署后如何用Heroku基本URL替换它。
我在本地运行时一直收到一些CORS错误,但是我安装并实现了cors节点软件包,这似乎可以解决问题。
我正在使用以下脚本在同一个Heroku Web应用程序上部署angular和node程序:
"scripts": {
"prestart": "node server",
"start": "http-server ./dist/",
"ng": "ng",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
在我的user.component.ts中:
ngOnInit(): void {
//alertbox code;
setTimeout(() => this.staticAlertClosed = true, 20000);
this._success.subscribe((message) => this.successMessage = message);
this._success.pipe(
debounceTime(5000)
).subscribe(() => this.successMessage = null);
//this.router.navigate([""]);
this.router.params.subscribe(params => {
//assign it to some component member, like
this.theName = params['username'];
});
console.log("alright we're starting this thing w user " + this.theName);
//Get the calendar
this.eventService.getCalendar().subscribe(calendar => {
this.eventsList = calendar
console.log("events list should show up here")
console.log(this.eventsList);
this.isDataAvailable = true;
return this.eventsList;
})
}
event.service.ts:
export class EventService {
constructor(private http: HttpClient) { }
PORT = 'process.env.PORT' || '3000';
api_url = `http://localhost:${this.PORT}`;
newcalUrl = `${this.api_url}/api`;
//Get the list of events
getCalendar(): Observable<Object>{
return this.http.get(this.newcalUrl);
}
}
我的server.js:
const express = require('express');
const path = require('path');
var http = require('http');
const bodyParser = require('body-parser');
const PORT = process.env.PORT || 3000;
// Get our API routes
const api = require('./server/routes/api');
var cors = require('cors');
var app = express();
app.use(cors());
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
// Set our api routes
app.use('/api', api);
// Catch all other routes and return the index file
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/newcal-angular/index.html'));
});
/**
* Get port from environment and store in Express.
*/
app.set('port', PORT);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(PORT, () => console.log(`API running on localhost:${PORT}`));
API.js....
const express = require('express');
const router = express.Router();
const CAL_ID = "[MY_CAL]@group.calendar.google.com";
var events;
/* GET api listing. */
router.get('/', (req, res, Data) => {
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
....lots more google code.....
}