我有一个应用程序,当用户登录时,他收到一些数据作为响应,但是如果响应不是我所期望的,应用程序就会崩溃。
让我向你们展示如下:
我创建了一个接口来告诉类型记录我所期望的数据。
export interface AuthResponseData {
token: string;
expires: string;
role: number;
}然后,我创建了一个将登录数据发送到服务器的方法。
login(user: string, password: string){
return this.http.post<AuthResponseData>(
'https://localhost:44344/api/auth', { user: user, pwd: password }
).pipe(
catchError(this.handleError),
tap(resData => { this.handleAuthentication(resData.token, resData.expires, resData.role)})
);
}我原以为,如果来自服务器的响应与接口不匹配,那么角将重定向到catchError。但不会发生。
现在我的问题是:是否有任何方法检查API响应是否等于接口,如果不是,则抛出错误。还是我要求的不可能?
更新:
搜索之后,我发现接口在运行时消失了,因此无法将api响应与接口进行比较(据我所知)。但我一直在寻找一种动态方式检查api响应的方法。我认为它并不是真正安全的,取决于api响应是否总是正确的。所以我应该检查API响应。我怎么能这么做?
希望你能帮我,谢谢
发布于 2020-02-20 20:03:30
正如您已经注意到的,interface纯粹是TypeScript,它在JavaScript中不存在,也没有以任何方式被模仿(就像private、protected、public和其他一些东西)。TypeScript中的类型检查只允许有一个“快速失败”的逻辑(您不必运行该应用程序就会注意到您自己的代码或第三方库正在被滥用,它在编译时失败了)。
你的角度应用程序只是一个UI,没有关键的操作(它们应该在你的后端),所以我不认为因为类型错配而抛出错误是个好主意,而不是试图尽可能地满足用户。据我所知,后端应该验证客户端输入,而客户端应该尝试适应后端服务。
尽管如此,这里有一个用于JSON验证的草案,https://json-schema.org/和一些库实现了它(例如:https://github.com/epoberezkin/ajv)。这将允许您获得所需的行为。
发布于 2020-02-20 13:42:23
你的问题中有三个问题,再加上我(最后)提出的一个问题,以便更好地理解:
我问这个问题是因为如果我有一个返回100个属性的端点,我必须手动检查100,对吗?
这是基于从API响应返回的模型编写interface的正确方法。如果一个端点返回一个包含100个属性的模型,正确的方法是使用相同的属性编写相关的类型记录interface,可能是使用类似于json2ts的工具。这样可以进行类型检查,避免不必要的编程错误,而不需要任何代价,因为运行时不存在interface。
是否有任何方法检查API响应是否等于接口,如果不是,则抛出错误。还是我要求的不可能?
您可以在tap中检查一个键值以检测条件(null)。
我原以为,如果来自服务器的响应与接口不匹配,那么角将重定向到
catchError。但不会发生。
interface失配不会被认为是RxJS的catchError。当像400这样的请求错误发生时,它会触发(糟糕的请求)。注意,类型检查意味着一旦您将变量声明为某一类型,则编译器的任务是确保它只被分配给该类型的值(或属于该类型的子类型的值)。
是否有办法为所有端点建立动态模型?
有些人使用括号表示法提取响应值。在JavaScript中,括号表示法和点表示法在功能上是等价的,但在TypeScript中却不是一回事。TypeScript对括号表示法不那么严格,这种行为是有意提供某种后门的。我不建议这样做,这会使代码变得肮脏和错误。
发布于 2020-02-19 11:06:01
要检查API响应是否有效,请使用类而不是接口,并给它一个isValid函数和/或检查构造函数中的数据。
例如:
interface IAuthResponseData {
token: string;
expires: string;
role: string;
}
class AuthResponseData implements IAuthResponseData {
public token: string;
public expires: string;
private __expires: Date;
public role: string;
public constructor(data: IAuthResponseData) {
this.token = data.token;
this.expires = data.expires;
this.__expires = new Date(data.expires);
this.role = data.role;
if (!this.isValid()) {
throw new Error("Invalid Parameters")
}
}
public isValid(): boolean {
// simple equals check against null is also true when the value is undefined
for (let member in this) {
if (this[member] == null) {
return false;
}
}
return true;
}
}请记住捕捉错误并对其进行操作,或者将检查从构造函数中删除,而是在创建对象之后进行检查,然后对其执行操作。
https://stackoverflow.com/questions/60190992
复制相似问题