Angular Universal集成GRPC出现XHR不支持二进制传输问题求助
问题原因
这个错误本质是Angular SSR运行在Node.js环境时,默认的XHR模拟实现不支持gRPC需要的二进制传输协议,只有浏览器环境原生支持对应二进制传输能力,所以关闭SSR、本地开发(走浏览器端渲染)时都正常,生产SSR环境就报错。
解决方案
方案1:配置服务端跳过gRPC调用,仅在客户端执行gRPC请求
这是适配成本最低的方案,绝大多数业务场景下gRPC请求都是和用户交互、页面动态数据相关的,不需要在SSR阶段执行:
- 导入
PLATFORM_ID标记,用isPlatformBrowser判断运行环境,只有浏览器环境下才发起gRPC调用 - 代码示例:
import { PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Component({ // 你的组件配置 }) export class YourComponent { constructor( @Inject(PLATFORM_ID) private platformId: Object, // 你的gRPC服务注入 private grpcService: YourGrpcService ) {} ngOnInit() { if (isPlatformBrowser(this.platformId)) { // 仅在客户端执行gRPC请求 this.grpcService.yourMethod().subscribe(res => { // 处理返回结果 }) } } }
方案2:给Node服务端配置支持二进制的gRPC调用环境
如果确实需要在SSR阶段发起gRPC请求,就给服务端适配Node环境的gRPC依赖:
- 首先安装Node端的gRPC依赖:
npm install @grpc/grpc-js @grpc/proto-loader - 在Angular Universal的服务端入口文件(通常是
server.ts)中,替换gRPC客户端的传输实现,不要用默认的gRPC-web传输,改用Node原生的gRPC传输实现 - 针对你用的gRPC客户端库做传输层的环境区分注入:服务端注入Node原生gRPC传输,客户端注入gRPC-web传输
- 额外注意Node端请求gRPC服务不需要走浏览器的CORS规则,直接配置服务端gRPC地址即可
方案3:替换XHR模拟实现的配置
如果不想改业务代码,也可以在server.ts中修改全局XHR的配置,开启二进制支持:
// 在server.ts最顶部添加 global.XMLHttpRequest = require('xhr2'); global.XMLHttpRequest.prototype._restrictedHeaders = {}; // 开启二进制传输支持 global.XMLHttpRequest.prototype.binaryType = 'arraybuffer';
内容的提问来源于stack exchange,提问作者Vulovic Vukasin
相关产品推荐
相关产品推荐

