Javascript AJAX调用后如何向SPA网站用户提供反馈的选项

Javascript AJAX调用后如何向SPA网站用户提供反馈的选项,javascript,reactjs,ajax,single-page-application,Javascript,Reactjs,Ajax,Single Page Application,我在React.js中建立了SPA网站。当来自不同用户交互的AJAX调用成功/失败/挂起时,有哪些选项可以通知此网站的用户 我只知道网站角落里的Toastr风格的消息,但这些消息对我来说似乎是垃圾邮件和不雅的: 谷歌控制台:(下中) 常用的toastr lib:(通常位于右上方) 还有其他常用的可能性吗 我所说的用户交互AJAX调用示例: 当用户单击绿色的“检查”按钮时,当前行的状态将被异步更改(AJAX调用以更新行状态)。AJAX可以成功也可以失败。如何通知用户状态已更改或未更改?(成功时

我在React.js中建立了SPA网站。当来自不同用户交互的AJAX调用成功/失败/挂起时,有哪些选项可以通知此网站的用户

我只知道网站角落里的Toastr风格的消息,但这些消息对我来说似乎是垃圾邮件和不雅的:

谷歌控制台:(下中)

常用的toastr lib:(通常位于右上方)

还有其他常用的可能性吗

我所说的用户交互AJAX调用示例:

当用户单击绿色的“检查”按钮时,当前行的状态将被异步更改(AJAX调用以更新行状态)。AJAX可以成功也可以失败。如何通知用户状态已更改或未更改?(成功时,我也会禁用check按钮,但有些用户可能会错过它)

最好的方法是连接某种HttpInterceptor。我不确定您是如何发出HTTP请求的,但是像axios这样的库支持这个概念。Angular也可以,但您使用的是react

这里有一个例子,我是如何做到这一点的角度。基本上,我使用HttpInterceptor应用jwt凭据,并在出现问题时通过snackbar(toast)向用户提供反馈。如果您使用的是声誉良好的HTTP库,您应该能够将其转换为HTTP侦听器设置

intercept( _request: HttpRequest<any>, _next: HttpHandler): Observable<HttpEvent<any>> {
    return this._store.select(state => state.authState?.token).pipe(
        take(1),
        exhaustMap( token => {
            const req = token ? _request.clone({
                headers: new HttpHeaders({ Authorization: `Bearer ${token}`})
            }) : _request.clone();
            return _next.handle(req).pipe(
                catchError( (_error: any, _caught: any) => {
                    switch ( _error.status ) {
                        case 400:
                            if (_error.error && _error.error !== '') {
                                this._uiService.showSnackbar(_error.error);
                            } else {
                                this._uiService.showSnackbar(`400: Bad Request`);
                            }
                            break;
                        case 401:
                            this._router.navigateByUrl('/login').then();
                            break;
                        case 403:
                            this._uiService.showSnackbar('Access Denied');
                            break;
                        case 404:
                            this._uiService.showSnackbar(_error.error || `404: Resource not found`);
                            break;
                        case 500:
                            if (_error.error && _error.error !== '') {
                                this._uiService.showSnackbar(`Exception: ${_error.message}`, 30);
                            } else {
                                this._uiService.showSnackbar(`500: An error occurred on the server`);
                            }
                            break;
                    }
                    return of(_error);
                })
            );
        })
    );
}
intercept(\u请求:HttpRequest,\u下一步:HttpHandler):可观察{
返回此。\u store.select(state=>state.authState?.token).pipe(
以(1)为例,
排气图(标记=>{
const req=令牌?\u request.clone({
标头:新的HttpHeaders({授权:`Bearer${token}`})
}):_request.clone();
返回下一个句柄(请求)管道(
catchError((\u error:any,\u catch:any)=>{
开关(_error.status){
案例400:
如果(_error.error&&_error.error!=''){
这是.\u uiService.showSnackbar(\u error.error);
}否则{
这个.u uiService.showSnackbar(`400:Bad Request`);
}
打破
案例401:
这个。_router.navigateByUrl('/login')。然后();
打破
案例403:
这是。_uiService.showSnackbar(“拒绝访问”);
打破
案例404:
这是。_uiService.showSnackbar(_error.error | | `404:Resource not found`);
打破
案例500:
如果(_error.error&&_error.error!=''){
这个.u uiService.showSnackbar(`Exception:${{u error.message}`,30);
}否则{
此.u uiService.showSnackbar(`500:服务器上发生错误`);
}
打破
}
返回(_错误);
})
);
})
);
}
这很好:)谢谢。但我不是在问这个问题。我问了更多关于实际UI可能性和方法的问题。