{"id":13451375,"url":"https://github.com/grpc/grpc-web","last_synced_at":"2025-05-12T03:38:07.854Z","repository":{"id":37687787,"uuid":"61567304","full_name":"grpc/grpc-web","owner":"grpc","description":"gRPC for Web Clients","archived":false,"fork":false,"pushed_at":"2025-04-20T21:55:04.000Z","size":1433,"stargazers_count":8889,"open_issues_count":207,"forks_count":781,"subscribers_count":197,"default_branch":"master","last_synced_at":"2025-05-09T03:01:52.722Z","etag":null,"topics":["grpc","javascript","web"],"latest_commit_sha":null,"homepage":"https://grpc.io","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grpc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-06-20T17:34:33.000Z","updated_at":"2025-05-07T18:04:03.000Z","dependencies_parsed_at":"2023-11-08T06:04:55.189Z","dependency_job_id":"f2d47e81-8b52-4b0e-97ad-a90b8975b10c","html_url":"https://github.com/grpc/grpc-web","commit_stats":{"total_commits":744,"total_committers":131,"mean_commits":5.679389312977099,"dds":0.538978494623656,"last_synced_commit":"9856bfea5d9d301d3783d220cccf41e869dfbdf1"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc%2Fgrpc-web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc%2Fgrpc-web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc%2Fgrpc-web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grpc%2Fgrpc-web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grpc","download_url":"https://codeload.github.com/grpc/grpc-web/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253669069,"owners_count":21945056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grpc","javascript","web"],"created_at":"2024-07-31T07:00:52.818Z","updated_at":"2025-05-12T03:38:07.828Z","avatar_url":"https://github.com/grpc.png","language":"JavaScript","readme":"# gRPC Web \u0026middot; [![npm version](https://img.shields.io/npm/v/grpc-web.svg?style=flat)](https://www.npmjs.com/package/grpc-web)\n\nA JavaScript implementation of [gRPC][] for browser clients. For more information,\nincluding a **quick start**, see the [gRPC-web documentation][grpc-web-docs].\n\ngRPC-web clients connect to gRPC services via a special proxy; by default,\ngRPC-web uses [Envoy][].\n\nIn the future, we expect gRPC-web to be supported in language-specific web\nframeworks for languages such as Python, Java, and Node. For details, see the\n[roadmap](doc/roadmap.md).\n\n## Streaming Support\ngRPC-web currently supports 2 RPC modes:\n- Unary RPCs ([example](#make-a-unary-rpc-call))\n- Server-side Streaming RPCs ([example](#server-side-streaming)) (NOTE: Only when [`grpcwebtext`](#wire-format-mode) mode is used.)\n\nClient-side and Bi-directional streaming is not currently supported (see [streaming roadmap](doc/streaming-roadmap.md)).\n\n## Quick Start\n\nEager to get started? Try the [Hello World example][]. From this example, you'll\nlearn how to do the following:\n\n - Define your service using protocol buffers\n - Implement a simple gRPC Service using NodeJS\n - Configure the Envoy proxy\n - Generate protobuf message classes and client service stub for the client\n - Compile all the JS dependencies into a static library that can be consumed\n   by the browser easily\n\n## Advanced Demo: Browser Echo App\n\nYou can also try to run a more advanced Echo app from the browser with a\nstreaming example.\n\nFrom the repo root directory:\n\n```sh\n$ docker-compose pull prereqs node-server envoy commonjs-client\n$ docker-compose up node-server envoy commonjs-client\n```\n\nOpen a browser tab, and visit http://localhost:8081/echotest.html.\n\nTo shutdown: `docker-compose down`.\n\n## Runtime Library\n\nThe gRPC-web runtime library is available at `npm`:\n\n```sh\n$ npm i grpc-web\n```\n\n## Code Generator Plugins\n\n### (Prerequisite) 1. Protobuf (`protoc`)\n\nIf you don't already have [`protoc`](https://github.com/protocolbuffers/protobuf)\ninstalled, download it first from [here](https://github.com/protocolbuffers/protobuf/releases) and install it on your PATH.\n\nIf you use Homebrew (on macOS), you could run:\n\n```sh\nbrew install protobuf\n```\n\n### (Prerequisite) 2. Protobuf-javascript (`protoc-gen-js`)\n\nIf you don't have [`protoc-gen-js`](https://github.com/protocolbuffers/protobuf-javascript) installed, download it from [protocolbuffers/protobuf-javascript](https://github.com/protocolbuffers/protobuf-javascript/releases) and install it on your PATH.\n\nOr, use the [third-party](https://www.npmjs.com/package/protoc-gen-js) NPM installer:\n\n```\nnpm install -g protoc-gen-js\n```\n\n### 3. Install gRPC-Web Code Generator\n\nYou can download the `protoc-gen-grpc-web` protoc plugin from our\n[release](https://github.com/grpc/grpc-web/releases) page:\n\nMake sure all executables are discoverable from your PATH.\n\nFor example, on MacOS, you can do:\n\n```sh\nsudo mv protoc-gen-grpc-web-1.5.0-darwin-aarch64 \\\n    /usr/local/bin/protoc-gen-grpc-web\n\nchmod +x /usr/local/bin/protoc-gen-grpc-web\n```\n\n### (Optional) 4. Verify Installations\n\nYou can optionally verify the plugins works follwoing our [Hello world example](https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway/examples/helloworld#generating-stubs):\n\n```sh\ncd net/grpc/gateway/examples/helloworld\n\nprotoc -I=. helloworld.proto \\\n  --js_out=import_style=commonjs:. \\\n  --grpc-web_out=import_style=commonjs,mode=grpcwebtext:.\n```\n\nAfter the command runs successfully, you should now see two new files generated\nin the current directory. By running:\n\n```\nls -1 *_pb.js\n```\n\nInstallation is successful if you see the following 2 files:\n\n - `helloworld_pb.js` # Generated by `protoc-gen-js` plugin\n - `helloworld_grpc_web_pb.js` - Generated by gRPC-Web plugin\n\n## Client Configuration Options\n\nTypically, you will run the following command to generate the proto messages\nand the service client stub from your `.proto` definitions:\n\n```sh\nprotoc -I=$DIR echo.proto \\\n  --js_out=import_style=commonjs:$OUT_DIR \\\n  --grpc-web_out=import_style=commonjs,mode=grpcwebtext:$OUT_DIR\n```\n\nYou can then use Browserify, Webpack, Closure Compiler, etc. to resolve imports\nat compile time.\n\n### Import Style\n\n`import_style=closure`: The default generated code has\n[Closure](https://developers.google.com/closure/library/) `goog.require()`\nimport style.\n\n`import_style=commonjs`: The\n[CommonJS](https://requirejs.org/docs/commonjs.html) style `require()` is\nalso supported.\n\n`import_style=commonjs+dts`: (Experimental) In addition to above, a `.d.ts`\ntypings file will also be generated for the protobuf messages and service stub.\n\n`import_style=typescript`: (Experimental) The service stub will be generated\nin TypeScript. See **TypeScript Support** below for information on how to\ngenerate TypeScript files.\n\n\u003e **Note:** The `commonjs+dts` and `typescript` styles are only supported by\n`--grpc-web_out=import_style=...`, not by `--js_out=import_style=...`.\n\n### Wire Format Mode\n\nFor more information about the gRPC-web wire format, see the\n[specification](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2).\n\n`mode=grpcwebtext`: The default generated code sends the payload in the\n`grpc-web-text` format.\n\n  - `Content-type: application/grpc-web-text`\n  - Payload are base64-encoded.\n  - Both unary and server streaming calls are supported.\n\n`mode=grpcweb`: A binary protobuf format is also supported.\n\n  - `Content-type: application/grpc-web+proto`\n  - Payload are in the binary protobuf format.\n  - Only unary calls are supported.\n\n## How It Works\n\nLet's take a look at how gRPC-web works with a simple example. You can find out\nhow to build, run and explore the example yourself in\n[Build and Run the Echo Example](net/grpc/gateway/examples/echo).\n\n### 1. Define your service\n\nThe first step when creating any gRPC service is to define it. Like all gRPC\nservices, gRPC-web uses\n[protocol buffers](https://developers.google.com/protocol-buffers) to define\nits RPC service methods and their message request and response types.\n\n```protobuf\nmessage EchoRequest {\n  string message = 1;\n}\n\n...\n\nservice EchoService {\n  rpc Echo(EchoRequest) returns (EchoResponse);\n\n  rpc ServerStreamingEcho(ServerStreamingEchoRequest)\n      returns (stream ServerStreamingEchoResponse);\n}\n```\n\n### 2. Run the server and proxy\n\nNext you need to have a gRPC server that implements the service interface and a\ngateway proxy that allows the client to connect to the server. Our example\nbuilds a simple Node gRPC backend server and the Envoy proxy.\n\nFor the Echo service: see the\n[service implementations](net/grpc/gateway/examples/echo/node-server/server.js).\n\nFor the Envoy proxy: see the\n[config yaml file](net/grpc/gateway/examples/echo/envoy.yaml).\n\n### 3. Write your JS client\n\nOnce the server and gateway are up and running, you can start making gRPC calls\nfrom the browser!\n\nCreate your client:\n\n```js\nvar echoService = new proto.mypackage.EchoServiceClient(\n  'http://localhost:8080');\n```\n\n#### Make a unary RPC call:\n\n```js\nvar request = new proto.mypackage.EchoRequest();\nrequest.setMessage(msg);\nvar metadata = {'custom-header-1': 'value1'};\nechoService.echo(request, metadata, function(err, response) {\n  if (err) {\n    console.log(err.code);\n    console.log(err.message);\n  } else {\n    console.log(response.getMessage());\n  }\n});\n```\n\n#### Server-side streaming:\n\n```js\nvar stream = echoService.serverStreamingEcho(streamRequest, metadata);\nstream.on('data', function(response) {\n  console.log(response.getMessage());\n});\nstream.on('status', function(status) {\n  console.log(status.code);\n  console.log(status.details);\n  console.log(status.metadata);\n});\nstream.on('end', function(end) {\n  // stream end signal\n});\n\n// to close the stream\nstream.cancel()\n```\n\nFor an in-depth tutorial, see [this\npage](net/grpc/gateway/examples/echo/tutorial.md).\n\n## Setting Deadline\n\nYou can set a deadline for your RPC by setting a `deadline` header. The value\nshould be a Unix timestamp, in milliseconds.\n\n```js\nvar deadline = new Date();\ndeadline.setSeconds(deadline.getSeconds() + 1);\n\nclient.sayHelloAfterDelay(request, {deadline: deadline.getTime().toString()},\n  (err, response) =\u003e {\n    // err will be populated if the RPC exceeds the deadline\n    ...\n  });\n```\n\n## TypeScript Support\n\nThe `grpc-web` module can now be imported as a TypeScript module. This is\ncurrently an experimental feature. Any feedback welcome!\n\nWhen using the `protoc-gen-grpc-web` protoc plugin, mentioned above, pass in\neither:\n\n - `import_style=commonjs+dts`: existing CommonJS style stub + `.d.ts` typings\n - `import_style=typescript`: full TypeScript output\n\nDo *not* use `import_style=typescript` for `--js_out`, it will silently be\nignored. Instead you should use `--js_out=import_style=commonjs`, or\n`--js_out=import_style=commonjs,binary` if you are using `mode=grpcweb`. The\n`--js_out` plugin will generate JavaScript code (`echo_pb.js`), and the\n`-grpc-web_out` plugin will generate a TypeScript definition file for it\n(`echo_pb.d.ts`). This is a temporary hack until the `--js_out` supports\nTypeScript itself.\n\nFor example, this is the command you should use to generate TypeScript code\nusing the binary wire format\n\n```sh\nprotoc -I=$DIR echo.proto \\\n  --js_out=import_style=commonjs,binary:$OUT_DIR \\\n  --grpc-web_out=import_style=typescript,mode=grpcweb:$OUT_DIR\n```\n\nIt will generate the following files:\n\n* `EchoServiceClientPb.ts` - Generated by `--grpc-web_out`, contains the\nTypeScript gRPC-web code.\n* `echo_pb.js` - Generated by `--js_out`, contains the JavaScript Protobuf\ncode.\n* `echo_pb.d.ts` - Generated by `--grpc-web_out`, contains TypeScript\ndefinitions for `echo_pb.js`.\n\n### Using Callbacks\n\n```ts\nimport * as grpcWeb from 'grpc-web';\nimport {EchoServiceClient} from './EchoServiceClientPb';\nimport {EchoRequest, EchoResponse} from './echo_pb';\n\nconst echoService = new EchoServiceClient('http://localhost:8080', null, null);\n\nconst request = new EchoRequest();\nrequest.setMessage('Hello World!');\n\nconst call = echoService.echo(request, {'custom-header-1': 'value1'},\n  (err: grpcWeb.RpcError, response: EchoResponse) =\u003e {\n    console.log(response.getMessage());\n  });\ncall.on('status', (status: grpcWeb.Status) =\u003e {\n  // ...\n});\n```\n\n(See [here](https://github.com/grpc/grpc-web/blob/4d7dc44c2df522376394d3e3315b7ab0e010b0c5/packages/grpc-web/index.d.ts#L29-L39) full list of possible `.on(...)` callbacks)\n\n### (Option) Using Promises (Limited features)\n\n\u003e **NOTE:** It is not possible to access the `.on(...)` callbacks (e.g. for `metadata` and `status`) when Promise is used.\n\n```ts\n// Create a Promise client instead\nconst echoService = new EchoServicePromiseClient('http://localhost:8080', null, null);\n\n... (same as above)\n\nthis.echoService.echo(request, {'custom-header-1': 'value1'})\n  .then((response: EchoResponse) =\u003e {\n    console.log(`Received response: ${response.getMessage()}`);\n  }).catch((err: grpcWeb.RpcError) =\u003e {\n    console.log(`Received error: ${err.code}, ${err.message}`);\n  });\n```\n\nFor the full TypeScript example, see\n[ts-example/client.ts](net/grpc/gateway/examples/echo/ts-example/client.ts) with the [instructions](net/grpc/gateway/examples/echo/ts-example) to run.\n\n## Custom Interceptors\n\nCustom interceptors can be implemented and chained, which could be useful for features like auth, retries, etc.\n\nThere are 2 types of interceptors ([interfaces](https://github.com/grpc/grpc-web/blob/3cd7e0d43493d4694fed78400e4ad78031d70c09/packages/grpc-web/index.d.ts#L55-L65)):\n\n- `UnaryInterceptor` ([doc](https://grpc.io/blog/grpc-web-interceptor/#stream-interceptor-example), [example](https://github.com/grpc/grpc-web/blob/master/packages/grpc-web/test/tsc-tests/client04.ts)) - Intercept Unary RPCs; can only be used with Promise clients.\n- `StreamInterceptor` ([doc](https://grpc.io/blog/grpc-web-interceptor/#stream-interceptor-example), [example](https://github.com/grpc/grpc-web/blob/master/packages/grpc-web/test/tsc-tests/client03.ts)) - More versatile; can be used with regular clients.\n\nFor more details, see [this blog post](https://grpc.io/blog/grpc-web-interceptor/).\n\n\n## Ecosystem\n\n### Proxy Interoperability\n\nMultiple proxies support the gRPC-web protocol.\n\n1. The current **default proxy** is [Envoy][], which supports gRPC-web out of the box.\n\n\t```sh\n\t$ docker-compose up -d node-server envoy commonjs-client\n\t```\n\n2. You can also try the [gRPC-web Go proxy][].\n\n\t```sh\n\t$ docker-compose up -d node-server grpcwebproxy binary-client\n\t```\n\n3. Apache [APISIX](https://apisix.apache.org/) has also added grpc-web support, and more details can be found [here](https://apisix.apache.org/blog/2022/01/25/apisix-grpc-web-integration/).\n\n4. [Nginx](https://www.nginx.com/) has a grpc-web module ([doc](https://nginx.org/en/docs/http/ngx_http_grpc_module.html), [announcement](https://www.nginx.com/blog/nginx-1-13-10-grpc/))), and seems to work with simple configs, according to user [feedback](https://github.com/grpc/grpc-web/discussions/1322).\n\n### Server Frameworks with gRPC-Web support\n- [Armeria (JVM)](https://armeria.dev/docs/server-grpc/#grpc-web)\n- [Tonic (Rust)](https://docs.rs/tonic-web/latest/tonic_web/)\n\n### Web Frameworks Compatibility\n- **Vite** - See this [demo app](https://github.com/a2not/vite-grpc-web), as well as this [comment](https://github.com/grpc/grpc-web/issues/1242#issuecomment-1816249928).\n\n[Envoy]: https://www.envoyproxy.io\n[gRPC]: https://grpc.io\n[grpc-web-docs]: https://grpc.io/docs/languages/web\n[gRPC-web Go Proxy]: https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy\n[Hello World example]: net/grpc/gateway/examples/helloworld\n","funding_links":[],"categories":["JavaScript","Uncategorized","C++ (70)","C++","Official Libraries and Tools","网络服务","请求处理"],"sub_categories":["Uncategorized","网络服务_其他","调试"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrpc%2Fgrpc-web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrpc%2Fgrpc-web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrpc%2Fgrpc-web/lists"}