加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

localStorage未定义(Angular Universal)

发布时间:2020-12-17 07:06:04 所属栏目:安全 来源:网络整理
导读:我使用 universal-starter作为主干. 当我的客户端启动时,它会从localStorage读取有关用户信息的令牌. @Injectable()export class UserService { foo() {} bar() {} loadCurrentUser() { const token = localStorage.getItem('token'); // do other things };
我使用 universal-starter作为主干.

当我的客户端启动时,它会从localStorage读取有关用户信息的令牌.

@Injectable()
export class UserService {
  foo() {}

  bar() {}

  loadCurrentUser() {
    const token = localStorage.getItem('token');

    // do other things
  };
}

一切都很好,但是由于服务器渲染,我在服务器端(终端)得到了这个:

EXCEPTION: ReferenceError: localStorage is not defined

我从ng-conf-2016-universal-patterns获得了使用依赖注入来解决这个问题的想法.但那个演示真的很老了.

说我现在有这两个文件:

main.broswer.ts

export function ngApp() {
  return bootstrap(App,[
    // ...

    UserService
  ]);
}

main.node.ts

export function ngApp(req,res) {
  const config: ExpressEngineConfig = {
    // ...
    providers: [
      // ...
      UserService
    ]
  };

  res.render('index',config);
}

现在他们使用相同的UserService.有人可以提供一些代码来解释如何使用不同的依赖注入来解决这个问题吗?

如果有另一种更好的方式而不是依赖注入,那也很酷.

更新1我正在使用Angular 2 RC4,我尝试了@Martin的方式.但即使我导入它,它仍然在下面的终端给我错误:

终点站(npm开始)

/my-project/node_modules/@angular/core/src/di/reflective_provider.js:240
throw new reflective_exceptions_1.NoAnnotationError(typeOrFunc,params);
^ Error: Cannot resolve all parameters for ‘UserService'(Http,?). Make sure that all the parameters are decorated with Inject or
have valid type annotations and that ‘UserService’ is decorated with
Injectable.

终端(npm跑表)

error TS2304: Cannot find name ‘LocalStorage’.

我猜它是以某种方式与angular2-universal的LocalStorage重复(虽然我没有使用’angular2-universal’中的import {LocalStorage};),但即使我试图将我的更改为LocalStorage2,仍然无法正常工作.

同时,我的IDE WebStorm也显示为红色:

enter image description here

顺便说一下,我从’angular2-universal’中找到了一个导入{LocalStorage};但是不知道如何使用它.

更新2,我改为(不确定是否有更好的方法):

import { Injectable,Inject } from '@angular/core';
import { Http } from '@angular/http';
import { LocalStorage } from '../../local-storage';

@Injectable()
export class UserService {
  constructor (
    private _http: Http,@Inject(LocalStorage) private localStorage) {}  // <- this line is new

  loadCurrentUser() {
    const token = this.localStorage.getItem('token'); // here I change from `localStorage` to `this.localStorage`

    // …
  };
}

这解决了UPADAT 1中的问题,但现在终端出错了:

EXCEPTION: TypeError: this.localStorage.getItem is not a function

解决方法

更新版本的Angular

OpaqueToken被InjectionToken取代,它以相同的方式工作 – 除了它具有通用接口InjectionToken< T>这使得更好的类型检查和推断.

原始答案

两件事情:

>您没有注入任何包含localStorage对象的对象,而是尝试直接作为全局对象访问它.任何全球访问都应该是出现问题的第一个线索.
> nodejs中没有window.localStorage.

您需要做的是为localStorage注入一个适用于浏览器和NodeJS的适配器.这也将为您提供可测试的代码.

在local-storage.ts中:

import { OpaqueToken } from '@angular/core';

export const LocalStorage = new OpaqueToken('localStorage');

在main.browser.ts中,我们将从您的浏览器中注入实际的localStorage对象:

import {LocalStorage} from './local-storage.ts';

export function ngApp() {
  return bootstrap(App,[
    // ...

    UserService,{ provide: LocalStorage,useValue: window.localStorage}
  ]);

然后在main.node.ts中我们将使用一个空对象:

... 
providers: [
    // ...
    UserService,{provide: LocalStorage,useValue: {getItem() {} }}
]
...

然后你的服务注入了这个:

import { LocalStorage } from '../local-storage';

export class UserService {

    constructor(@Inject(LocalStorage) private localStorage: LocalStorage) {}

    loadCurrentUser() {

        const token = this.localStorage.getItem('token');
        ...
    };
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读