@reskin/core 0.0.21 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/reskin-core-directives.umd.js +303 -163
- package/bundles/reskin-core-directives.umd.js.map +1 -1
- package/bundles/reskin-core-guards.umd.js +119 -32
- package/bundles/reskin-core-guards.umd.js.map +1 -1
- package/bundles/reskin-core-interceptors.umd.js +310 -92
- package/bundles/reskin-core-interceptors.umd.js.map +1 -1
- package/bundles/reskin-core-utils.umd.js +220 -77
- package/bundles/reskin-core-utils.umd.js.map +1 -1
- package/directives/auth.directive.d.ts +56 -9
- package/directives/load.styles.directive.d.ts +45 -5
- package/directives/string.template.outlet.directive.d.ts +68 -11
- package/esm2015/directives/auth.directive.js +71 -30
- package/esm2015/directives/load.styles.directive.js +84 -15
- package/esm2015/directives/string.template.outlet.directive.js +118 -60
- package/esm2015/guards/auth.guard.js +117 -30
- package/esm2015/interceptors/blob.interceptor.js +67 -28
- package/esm2015/interceptors/cache.interceptor.js +46 -14
- package/esm2015/interceptors/error.interceptor.js +104 -12
- package/esm2015/interceptors/public-api.js +2 -1
- package/esm2015/interceptors/token.interceptor.js +86 -42
- package/esm2015/interceptors/types.js +5 -0
- package/esm2015/utils/array.js +42 -22
- package/esm2015/utils/dom.js +29 -11
- package/esm2015/utils/form.js +44 -13
- package/esm2015/utils/store.js +101 -26
- package/fesm2015/reskin-core-directives.js +269 -103
- package/fesm2015/reskin-core-directives.js.map +1 -1
- package/fesm2015/reskin-core-guards.js +116 -29
- package/fesm2015/reskin-core-guards.js.map +1 -1
- package/fesm2015/reskin-core-interceptors.js +302 -91
- package/fesm2015/reskin-core-interceptors.js.map +1 -1
- package/fesm2015/reskin-core-utils.js +212 -68
- package/fesm2015/reskin-core-utils.js.map +1 -1
- package/guards/auth.guard.d.ts +85 -5
- package/interceptors/blob.interceptor.d.ts +30 -3
- package/interceptors/cache.interceptor.d.ts +28 -4
- package/interceptors/error.interceptor.d.ts +43 -2
- package/interceptors/public-api.d.ts +1 -0
- package/interceptors/token.interceptor.d.ts +41 -12
- package/interceptors/types.d.ts +68 -0
- package/package.json +1 -1
- package/utils/array.d.ts +8 -1
- package/utils/dom.d.ts +32 -5
- package/utils/form.d.ts +37 -2
- package/utils/store.d.ts +56 -15
|
@@ -503,31 +503,54 @@
|
|
|
503
503
|
__disposeResources: __disposeResources,
|
|
504
504
|
};
|
|
505
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Token 拦截器常量
|
|
508
|
+
*/
|
|
509
|
+
var DEFAULT_TOKEN_HEADER_NAME = 'Authorization';
|
|
510
|
+
var TOKEN_CONTROL_HEADER = 'Token-Control';
|
|
511
|
+
var CUSTOM_TOKEN_HEADER = 'Custom-Token';
|
|
512
|
+
var CUSTOM_TOKEN_HEADER_NAME = 'Custom-Token-Header';
|
|
513
|
+
var AUTH_ID_HEADER = 'X-Auth-Id';
|
|
514
|
+
/**
|
|
515
|
+
* Token 拦截器
|
|
516
|
+
* 自动为 HTTP 请求添加认证 Token
|
|
517
|
+
*/
|
|
506
518
|
var TokenInterceptor = /** @class */ (function () {
|
|
507
|
-
function TokenInterceptor(
|
|
508
|
-
this.
|
|
519
|
+
function TokenInterceptor(authService) {
|
|
520
|
+
this.authService = authService;
|
|
509
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* 拦截 HTTP 请求,添加 Token 认证信息
|
|
524
|
+
* @param request HTTP 请求对象
|
|
525
|
+
* @param next 下一个拦截器处理器
|
|
526
|
+
* @returns Observable<HttpEvent<unknown>>
|
|
527
|
+
*/
|
|
510
528
|
TokenInterceptor.prototype.intercept = function (request, next) {
|
|
511
|
-
var
|
|
512
|
-
//
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
529
|
+
var tokenControl = request.headers.get(TOKEN_CONTROL_HEADER);
|
|
530
|
+
// 如果明确指定不需要 Token,直接放行
|
|
531
|
+
if (tokenControl === 'no-token') {
|
|
532
|
+
return next.handle(request);
|
|
533
|
+
}
|
|
534
|
+
var customToken = request.headers.get(CUSTOM_TOKEN_HEADER);
|
|
535
|
+
var customTokenHeaderName = request.headers.get(CUSTOM_TOKEN_HEADER_NAME) || DEFAULT_TOKEN_HEADER_NAME;
|
|
536
|
+
var headers = {};
|
|
537
|
+
if (customToken) {
|
|
538
|
+
// 使用自定义 Token
|
|
539
|
+
headers[customTokenHeaderName] = customToken;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
// 使用默认认证信息
|
|
543
|
+
var auth = this.authService.token;
|
|
544
|
+
if (auth === null || auth === void 0 ? void 0 : auth.token) {
|
|
545
|
+
headers[DEFAULT_TOKEN_HEADER_NAME] = auth.token;
|
|
546
|
+
if (auth.id) {
|
|
547
|
+
headers[AUTH_ID_HEADER] = auth.id;
|
|
526
548
|
}
|
|
527
549
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
550
|
+
}
|
|
551
|
+
// 如果有需要添加的 Header,克隆请求并添加
|
|
552
|
+
if (Object.keys(headers).length > 0) {
|
|
553
|
+
request = request.clone({ setHeaders: headers });
|
|
531
554
|
}
|
|
532
555
|
return next.handle(request);
|
|
533
556
|
};
|
|
@@ -539,64 +562,157 @@
|
|
|
539
562
|
type: i0.Injectable
|
|
540
563
|
}], ctorParameters: function () { return [{ type: i1__namespace.RkAuthService }]; } });
|
|
541
564
|
/**
|
|
542
|
-
*
|
|
565
|
+
* 提供 Token 拦截器
|
|
566
|
+
* @returns Provider 配置对象
|
|
543
567
|
*/
|
|
544
568
|
function providerAuthToken() {
|
|
545
569
|
return { provide: http.HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true };
|
|
546
570
|
}
|
|
547
571
|
/**
|
|
548
|
-
*
|
|
549
|
-
* @param urls
|
|
550
|
-
* @param params
|
|
551
|
-
* @
|
|
572
|
+
* 创建不带 Token 的请求配置
|
|
573
|
+
* @param urls 模板字符串数组
|
|
574
|
+
* @param params 模板参数
|
|
575
|
+
* @returns [url, options] 元组
|
|
576
|
+
* @example
|
|
577
|
+
* this.http.get(...NoAuthTokenTemplate`/api/public/data`).subscribe();
|
|
552
578
|
*/
|
|
553
579
|
function NoAuthTokenTemplate(urls) {
|
|
580
|
+
var _a;
|
|
554
581
|
var params = [];
|
|
555
582
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
556
583
|
params[_i - 1] = arguments[_i];
|
|
557
584
|
}
|
|
558
|
-
var
|
|
559
|
-
|
|
560
|
-
url = String.raw.apply(String, __spreadArray([urls], __read(params)));
|
|
561
|
-
}
|
|
562
|
-
return [url, { headers: new http.HttpHeaders({ 'Token-Control': 'no-token' }) }];
|
|
585
|
+
var url = params.length > 0 ? String.raw.apply(String, __spreadArray([urls], __read(params))) : urls[0];
|
|
586
|
+
return [url, { headers: new http.HttpHeaders((_a = {}, _a[TOKEN_CONTROL_HEADER] = 'no-token', _a)) }];
|
|
563
587
|
}
|
|
564
588
|
/**
|
|
565
|
-
*
|
|
566
|
-
* @param
|
|
567
|
-
* @param
|
|
568
|
-
* @
|
|
589
|
+
* 创建使用自定义 Token 的请求配置
|
|
590
|
+
* @param token 自定义 Token 值
|
|
591
|
+
* @param urls 模板字符串数组
|
|
592
|
+
* @param params 模板参数
|
|
593
|
+
* @returns [url, options] 元组
|
|
594
|
+
* @example
|
|
595
|
+
* this.http.get(...CustomTokenTemplate('my-token', `/api/data`)).subscribe();
|
|
569
596
|
*/
|
|
570
|
-
function CustomTokenTemplate(urls) {
|
|
597
|
+
function CustomTokenTemplate(token, urls) {
|
|
598
|
+
var _a;
|
|
571
599
|
var params = [];
|
|
572
|
-
for (var _i =
|
|
573
|
-
params[_i -
|
|
600
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
601
|
+
params[_i - 2] = arguments[_i];
|
|
574
602
|
}
|
|
575
|
-
|
|
576
|
-
|
|
603
|
+
var url = params.length > 0 ? String.raw.apply(String, __spreadArray([urls], __read(params))) : urls[0];
|
|
604
|
+
return [url, { headers: new http.HttpHeaders((_a = {}, _a[CUSTOM_TOKEN_HEADER] = token, _a)) }];
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* 创建使用自定义 Token 和自定义 Header 名称的请求配置
|
|
608
|
+
* @param token 自定义 Token 值
|
|
609
|
+
* @param headerName 自定义 Header 名称
|
|
610
|
+
* @param urls 模板字符串数组
|
|
611
|
+
* @param params 模板参数
|
|
612
|
+
* @returns [url, options] 元组
|
|
613
|
+
* @example
|
|
614
|
+
* this.http.get(...CustomTokenWithHeaderTemplate('my-token', 'X-API-Key', `/api/data`)).subscribe();
|
|
615
|
+
*/
|
|
616
|
+
function CustomTokenWithHeaderTemplate(token, headerName, urls) {
|
|
617
|
+
var _a;
|
|
618
|
+
var params = [];
|
|
619
|
+
for (var _i = 3; _i < arguments.length; _i++) {
|
|
620
|
+
params[_i - 3] = arguments[_i];
|
|
577
621
|
}
|
|
578
|
-
var
|
|
579
|
-
|
|
580
|
-
|
|
622
|
+
var url = params.length > 0 ? String.raw.apply(String, __spreadArray([urls], __read(params))) : urls[0];
|
|
623
|
+
return [
|
|
624
|
+
url,
|
|
625
|
+
{
|
|
626
|
+
headers: new http.HttpHeaders((_a = {},
|
|
627
|
+
_a[CUSTOM_TOKEN_HEADER] = token,
|
|
628
|
+
_a[CUSTOM_TOKEN_HEADER_NAME] = headerName,
|
|
629
|
+
_a)),
|
|
630
|
+
},
|
|
631
|
+
];
|
|
581
632
|
}
|
|
582
633
|
|
|
634
|
+
/**
|
|
635
|
+
* 默认配置
|
|
636
|
+
*/
|
|
637
|
+
var DEFAULT_CONFIG = {
|
|
638
|
+
unauthorizedPath: '/errors/401',
|
|
639
|
+
enableLogging: false,
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* HTTP 错误拦截器
|
|
643
|
+
* 统一处理 HTTP 请求错误,包括 401 未授权错误的自动跳转
|
|
644
|
+
*/
|
|
583
645
|
var ErrorInterceptor = /** @class */ (function () {
|
|
584
646
|
function ErrorInterceptor(router) {
|
|
585
647
|
this.router = router;
|
|
648
|
+
this.config = DEFAULT_CONFIG;
|
|
586
649
|
}
|
|
650
|
+
/**
|
|
651
|
+
* 设置拦截器配置
|
|
652
|
+
* @param config 配置对象
|
|
653
|
+
*/
|
|
654
|
+
ErrorInterceptor.prototype.setConfig = function (config) {
|
|
655
|
+
this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
|
|
656
|
+
};
|
|
657
|
+
/**
|
|
658
|
+
* 拦截 HTTP 请求,处理错误响应
|
|
659
|
+
* @param request HTTP 请求对象
|
|
660
|
+
* @param next 下一个拦截器处理器
|
|
661
|
+
* @returns Observable<HttpEvent<unknown>>
|
|
662
|
+
*/
|
|
587
663
|
ErrorInterceptor.prototype.intercept = function (request, next) {
|
|
588
664
|
var _this = this;
|
|
589
|
-
return next.handle(request).pipe(operators.catchError(function (
|
|
590
|
-
|
|
591
|
-
if (
|
|
592
|
-
_this.
|
|
665
|
+
return next.handle(request).pipe(operators.catchError(function (error) {
|
|
666
|
+
// 处理 401 未授权错误
|
|
667
|
+
if (error.status === 401) {
|
|
668
|
+
_this.handleUnauthorizedError();
|
|
669
|
+
return rxjs.throwError(error);
|
|
593
670
|
}
|
|
594
|
-
|
|
595
|
-
|
|
671
|
+
// 记录错误日志
|
|
672
|
+
if (_this.config.enableLogging) {
|
|
673
|
+
console.error('[HTTP Error]', {
|
|
674
|
+
url: request.url,
|
|
675
|
+
method: request.method,
|
|
676
|
+
status: error.status,
|
|
677
|
+
message: error.message,
|
|
678
|
+
error: error.error,
|
|
679
|
+
});
|
|
596
680
|
}
|
|
597
|
-
|
|
681
|
+
// 提取错误信息
|
|
682
|
+
var errorMessage = _this.extractErrorMessage(error);
|
|
683
|
+
return rxjs.throwError(new Error(errorMessage));
|
|
598
684
|
}));
|
|
599
685
|
};
|
|
686
|
+
/**
|
|
687
|
+
* 处理 401 未授权错误
|
|
688
|
+
*/
|
|
689
|
+
ErrorInterceptor.prototype.handleUnauthorizedError = function () {
|
|
690
|
+
var path = this.config.unauthorizedPath || DEFAULT_CONFIG.unauthorizedPath;
|
|
691
|
+
this.router.navigate([path]).catch(function (err) {
|
|
692
|
+
console.error('导航到错误页面失败:', err);
|
|
693
|
+
});
|
|
694
|
+
};
|
|
695
|
+
/**
|
|
696
|
+
* 提取错误信息
|
|
697
|
+
* @param error HTTP 错误响应
|
|
698
|
+
* @returns 错误信息字符串
|
|
699
|
+
*/
|
|
700
|
+
ErrorInterceptor.prototype.extractErrorMessage = function (error) {
|
|
701
|
+
if (error.error) {
|
|
702
|
+
// 尝试从 error.error 中提取信息
|
|
703
|
+
if (typeof error.error === 'string') {
|
|
704
|
+
return error.error;
|
|
705
|
+
}
|
|
706
|
+
if (error.error.msg) {
|
|
707
|
+
return error.error.msg;
|
|
708
|
+
}
|
|
709
|
+
if (error.error.message) {
|
|
710
|
+
return error.error.message;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
// 使用默认错误信息
|
|
714
|
+
return error.message || "HTTP Error " + error.status;
|
|
715
|
+
};
|
|
600
716
|
return ErrorInterceptor;
|
|
601
717
|
}());
|
|
602
718
|
ErrorInterceptor.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0__namespace, type: ErrorInterceptor, deps: [{ token: i1__namespace$1.Router }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
|
|
@@ -605,28 +721,71 @@
|
|
|
605
721
|
type: i0.Injectable
|
|
606
722
|
}], ctorParameters: function () { return [{ type: i1__namespace$1.Router }]; } });
|
|
607
723
|
/**
|
|
608
|
-
*
|
|
724
|
+
* 提供 HTTP 错误拦截器
|
|
725
|
+
* @param config 可选的配置对象
|
|
726
|
+
* @returns Provider 配置对象
|
|
727
|
+
* @example
|
|
728
|
+
* providers: [
|
|
729
|
+
* providerHttpError({ unauthorizedPath: '/login', enableLogging: true })
|
|
730
|
+
* ]
|
|
609
731
|
*/
|
|
610
|
-
function providerHttpError() {
|
|
611
|
-
|
|
732
|
+
function providerHttpError(config) {
|
|
733
|
+
if (config) {
|
|
734
|
+
// 如果有配置,使用 useFactory
|
|
735
|
+
return {
|
|
736
|
+
provide: http.HTTP_INTERCEPTORS,
|
|
737
|
+
useFactory: function (router) {
|
|
738
|
+
var interceptor = new ErrorInterceptor(router);
|
|
739
|
+
interceptor.setConfig(config);
|
|
740
|
+
return interceptor;
|
|
741
|
+
},
|
|
742
|
+
deps: [i1$1.Router],
|
|
743
|
+
multi: true,
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// 没有配置,直接使用 useClass
|
|
748
|
+
return {
|
|
749
|
+
provide: http.HTTP_INTERCEPTORS,
|
|
750
|
+
useClass: ErrorInterceptor,
|
|
751
|
+
multi: true,
|
|
752
|
+
};
|
|
753
|
+
}
|
|
612
754
|
}
|
|
613
755
|
|
|
756
|
+
/**
|
|
757
|
+
* 缓存策略标识
|
|
758
|
+
*/
|
|
759
|
+
var CACHE_HEADER = 'Cache-Map';
|
|
760
|
+
var CACHE_STRATEGY = 'Storage';
|
|
761
|
+
/**
|
|
762
|
+
* HTTP 缓存拦截器
|
|
763
|
+
* 为 GET 请求提供缓存功能,减少重复请求
|
|
764
|
+
*/
|
|
614
765
|
var CacheInterceptor = /** @class */ (function () {
|
|
615
|
-
function CacheInterceptor(
|
|
616
|
-
this.
|
|
766
|
+
function CacheInterceptor(cacheHttpService) {
|
|
767
|
+
this.cacheHttpService = cacheHttpService;
|
|
617
768
|
}
|
|
769
|
+
/**
|
|
770
|
+
* 拦截 HTTP 请求,实现缓存逻辑
|
|
771
|
+
* @param request HTTP 请求对象
|
|
772
|
+
* @param next 下一个拦截器处理器
|
|
773
|
+
* @returns Observable<HttpEvent<unknown>>
|
|
774
|
+
*/
|
|
618
775
|
CacheInterceptor.prototype.intercept = function (request, next) {
|
|
619
|
-
//
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
var
|
|
624
|
-
if (!
|
|
625
|
-
|
|
626
|
-
|
|
776
|
+
// 只缓存 GET 请求且明确标记了缓存策略的请求
|
|
777
|
+
var cacheStrategy = request.headers.get(CACHE_HEADER);
|
|
778
|
+
if (request.method === 'GET' && cacheStrategy === CACHE_STRATEGY) {
|
|
779
|
+
// 尝试从缓存中获取响应
|
|
780
|
+
var cachedResponse = this.cacheHttpService.get(request.url);
|
|
781
|
+
if (!cachedResponse) {
|
|
782
|
+
// 缓存未命中,发起请求并缓存结果
|
|
783
|
+
cachedResponse = next.handle(request).pipe(operators.shareReplay(1));
|
|
784
|
+
this.cacheHttpService.set(request.url, cachedResponse);
|
|
627
785
|
}
|
|
628
|
-
return
|
|
786
|
+
return cachedResponse;
|
|
629
787
|
}
|
|
788
|
+
// 非缓存请求,直接放行
|
|
630
789
|
return next.handle(request);
|
|
631
790
|
};
|
|
632
791
|
return CacheInterceptor;
|
|
@@ -637,63 +796,118 @@
|
|
|
637
796
|
type: i0.Injectable
|
|
638
797
|
}], ctorParameters: function () { return [{ type: i1__namespace.RkCacheHttpService }]; } });
|
|
639
798
|
/**
|
|
640
|
-
*
|
|
799
|
+
* 提供 HTTP 缓存拦截器
|
|
800
|
+
* @returns Provider 配置对象
|
|
801
|
+
* @example
|
|
802
|
+
* providers: [providerHttpCache()]
|
|
641
803
|
*/
|
|
642
804
|
function providerHttpCache() {
|
|
643
805
|
return { provide: http.HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true };
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* 创建带缓存标记的 GET 请求配置
|
|
809
|
+
* @param urls 模板字符串数组
|
|
810
|
+
* @param params 模板参数
|
|
811
|
+
* @returns [url, options] 元组
|
|
812
|
+
* @example
|
|
813
|
+
* this.http.get(...CacheHttpTemplate`/api/data`).subscribe();
|
|
814
|
+
*/
|
|
815
|
+
function CacheHttpTemplate(urls) {
|
|
816
|
+
var _a;
|
|
817
|
+
var params = [];
|
|
818
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
819
|
+
params[_i - 1] = arguments[_i];
|
|
820
|
+
}
|
|
821
|
+
var url = params.length > 0 ? String.raw.apply(String, __spreadArray([urls], __read(params))) : urls[0];
|
|
822
|
+
return [url, { headers: new http.HttpHeaders((_a = {}, _a[CACHE_HEADER] = CACHE_STRATEGY, _a)) }];
|
|
644
823
|
}
|
|
645
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Blob 响应拦截器
|
|
827
|
+
* 处理文件下载请求中的 JSON 错误响应
|
|
828
|
+
*/
|
|
646
829
|
var BlobInterceptor = /** @class */ (function () {
|
|
647
830
|
function BlobInterceptor() {
|
|
648
831
|
}
|
|
832
|
+
/**
|
|
833
|
+
* 拦截 HTTP 请求,处理 Blob 类型响应
|
|
834
|
+
* @param request HTTP 请求对象
|
|
835
|
+
* @param next 下一个拦截器处理器
|
|
836
|
+
* @returns Observable<HttpEvent<T>>
|
|
837
|
+
*/
|
|
649
838
|
BlobInterceptor.prototype.intercept = function (request, next) {
|
|
650
839
|
var _this = this;
|
|
840
|
+
// 只处理 responseType 为 blob 的请求
|
|
651
841
|
if (request.responseType !== 'blob') {
|
|
652
842
|
return next.handle(request);
|
|
653
843
|
}
|
|
654
|
-
return next.handle(request).pipe(operators.switchMap(function (
|
|
844
|
+
return next.handle(request).pipe(operators.switchMap(function (event) { return _this.handleBlobResponse(event); }), operators.catchError(function (error) { return _this.handleBlobError(error); }));
|
|
655
845
|
};
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
846
|
+
/**
|
|
847
|
+
* 处理 Blob 响应事件
|
|
848
|
+
* @param event HTTP 事件
|
|
849
|
+
* @returns Observable<HttpEvent<any>>
|
|
850
|
+
*/
|
|
851
|
+
BlobInterceptor.prototype.handleBlobResponse = function (event) {
|
|
852
|
+
var _a;
|
|
853
|
+
// 只处理完整的响应事件
|
|
854
|
+
if (event.type !== http.HttpEventType.Response) {
|
|
659
855
|
return new rxjs.Observable(function (subscriber) {
|
|
660
|
-
subscriber.next(
|
|
856
|
+
subscriber.next(event);
|
|
661
857
|
subscriber.complete();
|
|
662
858
|
});
|
|
663
859
|
}
|
|
664
|
-
|
|
665
|
-
|
|
860
|
+
// 检查响应体是否为 JSON 类型(通常表示错误)
|
|
861
|
+
if (event instanceof http.HttpResponse && ((_a = event.body) === null || _a === void 0 ? void 0 : _a.type) === 'application/json') {
|
|
862
|
+
return this.convertBlobToJson(event.body);
|
|
666
863
|
}
|
|
667
864
|
return new rxjs.Observable(function (subscriber) {
|
|
668
|
-
subscriber.next(
|
|
865
|
+
subscriber.next(event);
|
|
669
866
|
subscriber.complete();
|
|
670
867
|
});
|
|
671
868
|
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
869
|
+
/**
|
|
870
|
+
* 处理 Blob 错误响应
|
|
871
|
+
* @param error HTTP 错误响应
|
|
872
|
+
* @returns Observable<HttpEvent<any>>
|
|
873
|
+
*/
|
|
874
|
+
BlobInterceptor.prototype.handleBlobError = function (error) {
|
|
875
|
+
var _a;
|
|
876
|
+
// 如果错误响应体是 JSON 类型的 Blob,转换为 JSON 对象
|
|
877
|
+
if (((_a = error.error) === null || _a === void 0 ? void 0 : _a.type) === 'application/json') {
|
|
878
|
+
return this.convertBlobToJson(error.error);
|
|
676
879
|
}
|
|
677
880
|
return new rxjs.Observable(function (subscriber) {
|
|
678
|
-
subscriber.error(
|
|
881
|
+
subscriber.error(error);
|
|
679
882
|
subscriber.complete();
|
|
680
883
|
});
|
|
681
884
|
};
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
885
|
+
/**
|
|
886
|
+
* 将 Blob 转换为 JSON 对象并抛出错误
|
|
887
|
+
* @param blob Blob 对象
|
|
888
|
+
* @returns Observable<HttpEvent<T>>
|
|
889
|
+
*/
|
|
890
|
+
BlobInterceptor.prototype.convertBlobToJson = function (blob) {
|
|
891
|
+
return new rxjs.Observable(function (subscriber) {
|
|
892
|
+
var reader = new FileReader();
|
|
893
|
+
reader.addEventListener('loadend', function () {
|
|
894
|
+
try {
|
|
895
|
+
var json = JSON.parse(reader.result);
|
|
896
|
+
subscriber.error(json);
|
|
897
|
+
}
|
|
898
|
+
catch (parseError) {
|
|
899
|
+
subscriber.error(parseError);
|
|
900
|
+
}
|
|
901
|
+
finally {
|
|
902
|
+
subscriber.complete();
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
reader.addEventListener('error', function () {
|
|
906
|
+
subscriber.error(new Error('读取 Blob 数据失败'));
|
|
693
907
|
subscriber.complete();
|
|
694
|
-
}
|
|
908
|
+
});
|
|
909
|
+
reader.readAsText(blob, 'utf-8');
|
|
695
910
|
});
|
|
696
|
-
reader.readAsText(blob, 'utf-8');
|
|
697
911
|
};
|
|
698
912
|
return BlobInterceptor;
|
|
699
913
|
}());
|
|
@@ -703,8 +917,10 @@
|
|
|
703
917
|
type: i0.Injectable
|
|
704
918
|
}] });
|
|
705
919
|
/**
|
|
706
|
-
*
|
|
707
|
-
*
|
|
920
|
+
* 提供 Blob 响应拦截器
|
|
921
|
+
* @returns Provider 配置对象
|
|
922
|
+
* @example
|
|
923
|
+
* providers: [providerDownBlob()]
|
|
708
924
|
*/
|
|
709
925
|
function providerDownBlob() {
|
|
710
926
|
return { provide: http.HTTP_INTERCEPTORS, useClass: BlobInterceptor, multi: true };
|
|
@@ -715,8 +931,10 @@
|
|
|
715
931
|
*/
|
|
716
932
|
|
|
717
933
|
exports.BlobInterceptor = BlobInterceptor;
|
|
934
|
+
exports.CacheHttpTemplate = CacheHttpTemplate;
|
|
718
935
|
exports.CacheInterceptor = CacheInterceptor;
|
|
719
936
|
exports.CustomTokenTemplate = CustomTokenTemplate;
|
|
937
|
+
exports.CustomTokenWithHeaderTemplate = CustomTokenWithHeaderTemplate;
|
|
720
938
|
exports.ErrorInterceptor = ErrorInterceptor;
|
|
721
939
|
exports.NoAuthTokenTemplate = NoAuthTokenTemplate;
|
|
722
940
|
exports.TokenInterceptor = TokenInterceptor;
|