[英]angular 4 universal - different component / module for server and browser
[英]Angular universal share cookies between browser and server
我使用以下示例在浏览器和服务器中集成 cookies: https://github.com/Angular-RU/universal-starter/blob/master/src/app/shared/storage/universal.storage.ts
不幸的是 cookies 似乎没有在浏览器和服务器之间共享。 我只看到我在浏览器端设置的 cookie。 所以我希望我的组件中的以下代码显示相同的 cookies:
export class DashboardComponent {
constructor(@Inject(PLATFORM_ID) platformId: Object,
cookieService: CookieService) {
if (isPlatformServer(platformId)) {
console.log('get server');
console.log(cookieService.getAll());
}
else {
console.log('set browser');
cookieService.put('test', 'test1');
}
}
}
因此,当我在浏览器中加载页面时,cookie 已设置。 当我刷新页面时,我希望 cookieService.getAll() 在服务器端返回一个值,但它是空的。 此外,在重新加载页面时,我可以在请求 header 中看到 cookies。我是不是遗漏了什么或者我理解错了什么?
这是我已经实现的代码:
应用程序模块.ts
export function getRequest(): any {
return { headers: { cookie: document.cookie } };
}
@NgModule({
declarations: [
AppComponent,
LoaderComponent
],
imports: [
AppRoutingModule,
BrowserModule.withServerTransition({ appId: 'serverApp' }),
BrowserTransferStateModule,
BrowserAnimationsModule,
SharedModule,
HttpClientModule,
TransferHttpCacheModule,
CookieModule.forRoot(),
],
exports: [SharedModule],
providers: [
...
UniversalStorage,
{
// The server provides these in main.server
provide: REQUEST,
useFactory: getRequest,
},
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.server.module.ts
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule
],
bootstrap: [AppComponent],
providers: [
{
provide: AppConfigService,
useFactory: (transferState: TransferState) => new AppConfigService(new AssetServerLoader(transferState)),
deps: [TransferState]
},
// https://github.com/Angular-RU/universal-starter/blob/master/src/app/app.server.module.ts
// https://github.com/Gorniv/ngx-universal/blob/master/lib/src/cookie/README.md#installation
{
provide: REQUEST,
useValue: { cookie: '', headers: {} },
},
{
provide: RESPONSE,
useValue: {},
},
{
provide: CookieService,
useClass: CookieBackendService
},
{
provide: NgxRequest,
useValue: { cookie: '', headers: {} },
},
{
provide: NgxResponse,
useValue: {},
},
UniversalStorage
]
})
export class AppServerModule {}
服务器.ts
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { existsSync } from 'fs';
import { join } from 'path';
import * as https from 'https';
import * as fs from 'fs';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
import { AppServerModule } from './src/main.server';
import * as cookieparser from 'cookie-parser';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/client-app/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, {
req,
providers: [
{
provide: APP_BASE_HREF,
useValue: req.baseUrl
},
// Added for CookieService
// for http and cookies
{
provide: REQUEST,
useValue: req,
},
{
provide: RESPONSE,
useValue: res,
},
/// for cookie
{
provide: 'NgxRequest', useValue: (req)
},
{
provide: 'NgxResponse', useValue: (res)
}
]
});
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4200;
// https://medium.com/@dnlcyan/local-angular-ssr-with-https-b9d305dc620d
// Start up the Node server
let server;
if (process.argv && process.argv.includes('--ssl')) {
console.log('Using SSL');
// https certificates
const privateKey = fs.readFileSync('localhost.key');
const certificate = fs.readFileSync('localhost.crt');
server = https.createServer({ key: privateKey, cert: certificate }, app());
}
else {
server = app();
}
server.use(cookieparser());
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
我找到了一个似乎有效的替代库: https://github.com/salemdar/ngx-cookie
Important is to also set the cookie in the request header in server.ts
server.get('*', (req, res) => {
req.cookies = req.headers.cookie;
我为库https://github.com/Gorniv/ngx-universal尝试了这个,我也是第一次使用它,但它没有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.