PageSourceSearch

https://kuizuo.cn/assets/js/487786e8.d57b1562.js

js kuizuo.cn collected 2026-09-25 21:10:10 UTC 30,302 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkblog=self.webpackChunkblog||[]).push([["2189"],{88523(e,n,s){s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>l,default:()=>p,frontMatter:()=>c,metadata:()=>t,toc:()=>a});var t=s(20999),r=s(25105),o=s(89999);let c={slug:"remote-call-browser-function",title:"RPC\u8FDC\u7A0B\u8C03\u7528\u6D4F\u89C8\u5668\u51FD\u6570",date:new Date("2021-10-09T00:00:00.000Z"),authors:"kuizuo",tags:["javascript","rpc","browser"],keywords:["javascript","rpc","browser"]},l,i={authorsImageUrls:[void 0]},a=[{value:"\u7B97\u6CD5\u4F8B\u5B50",id:"\u7B97\u6CD5\u4F8B\u5B50",level:2},{value:"\u5B9E\u73B0",id:"\u5B9E\u73B0",level:2},{value:"Nodejs \u5B9E\u73B0 Websocket \u670D\u52A1\u7AEF",id:"nodejs-\u5B9E\u73B0-websocket-\u670D\u52A1\u7AEF",level:3},{value:"\u5B89\u88C5 ws \u6A21\u5757",id:"\u5B89\u88C5-ws-\u6A21\u5757",level:4},{value:"\u4EE3\u7801\u4F8B\u5B50",id:"\u4EE3\u7801\u4F8B\u5B50",level:4},{value:"\u6D4F\u89C8\u5668\u5B9E\u73B0 websocket",id:"\u6D4F\u89C8\u5668\u5B9E\u73B0-websocket",level:3},{value:"\u4F18\u5316\u6267\u884C\u6D41\u7A0B",id:"\u4F18\u5316\u6267\u884C\u6D41\u7A0B",level:2},{value:"\u601D\u8DEF",id:"\u601D\u8DEF",level:2},{value:"\u6D4F\u89C8\u5668\u7AEF",id:"\u6D4F\u89C8\u5668\u7AEF",level:3},{value:"\u7528\u6237\u8C03\u7528\u7AEF",id:"\u7528\u6237\u8C03\u7528\u7AEF",level:3},{value:"websocket \u670D\u52A1\u7AEF",id:"websocket-\u670D\u52A1\u7AEF",level:3},{value:"HTTP \u534F\u8BAE\u8C03\u7528\u5B9E\u73B0",id:"http-\u534F\u8BAE\u8C03\u7528\u5B9E\u73B0",level:2},{value:"\u4EE3\u7801\u5730\u5740",id:"\u4EE3\u7801\u5730\u5740",level:2}];function d(e){let n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",img:"img",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"\u65E9\u95FB RPC\uFF08Remote Procedure Call\uFF09\u8FDC\u7A0B\u8FC7\u7A0B\u8C03\u7528\uFF0C\u8FD9\u4E00\u8BCD\u4E86\uFF0C\u5E94\u8BE5\u662F\u5728\u5B89\u5353\u9006\u5411\u7684\u65F6\u5019\u542C\u95FB\u7684\uFF0C\u5F53\u65F6\u5439\u5618\u7684\u610F\u601D\u662F\u8FD9\u6837\u7684\uFF0C\u901A\u8FC7\u53E6\u4E00\u4E2A\u8FDC\u7AEF\u670D\u52A1\u5668\u6765\u8C03\u7528\u5B89\u5353\u4EE3\u7801\u4E2D\u7684\u51FD\u6570\uFF0C\u5E76\u5C06\u6267\u884C\u540E\u7684\u7ED3\u679C\u8FD4\u56DE\u3002\u6BD4\u5982\u6709\u4E00\u4E2A\u52A0\u5BC6\u7B97\u6CD5\uFF0C\u5982\u679C\u8981\u5B9E\u73B0\u8131\u673A\uFF08\u8131\u79BB\u5F53\u524D\u73AF\u5883\uFF09\u8FD0\u884C\u7684\u8BDD\uFF0C\u5C31\u9700\u8981\u6263\u9664\u76F8\u5BF9\u5E94\u7684\u4EE3\u7801\uFF0C\u8865\u9F50\u5BF9\u5E94\u7684\u73AF\u5883\uFF08\u6A21\u5757\uFF0C\u4E0A\u4E0B\u6587\uFF0C\u8BED\u8A00\uFF09\uFF0C\u7136\u800C\u8981\u5728\u8865\u9F50\u8BE5\u52A0\u5BC6\u7B97\u6CD5\u7684\u73AF\u5883\u53EF\u4E0D\u597D\u5B9E\u73B0\uFF0C\u800C\u901A\u8FC7 RPC \u5219\u53EF\u4EE5\u514D\u9664\u6263\u4EE3\u7801\uFF0C\u901A\u8FC7\u6570\u636E\u901A\u4FE1\u6765\u8FBE\u5230\u8FDC\u7A0B\u8C03\u7528\u7684\u76EE\u7684\uFF0C\u542C\u8D77\u6765\u662F\u633A\u725B\u903C\u7684\uFF0C\u5B9E\u9645\u4E0A\u4E5F\u786E\u5B9E\u633A\u9A9A\u7684\u3002\u8FD9\u91CC\u6211\u5C06\u4EE5\u6D4F\u89C8\u5668\u4E0E\u672C\u5730\u642D\u5EFA\u4E00\u4E2A websocket \u6765\u5B9E\u73B0\u8C03\u7528\u6D4F\u89C8\u5668\u5185\u7684\u51FD\u6570\u3002"}),"\n","\n",(0,r.jsx)(n.h2,{id:"\u7B97\u6CD5\u4F8B\u5B50",children:"\u7B97\u6CD5\u4F8B\u5B50"}),"\n",(0,r.jsxs)(n.p,{children:["\u8FD9\u91CC\u6211\u6240\u91C7\u7528\u7684\u662F\u767E\u5EA6\u767B\u5F55\u7684\u5BC6\u7801\u52A0\u5BC6\u7B97\u6CD5\uFF0C\u5177\u4F53\u9006\u5411\u5B9E\u73B0\u5C31\u4E0D\u7EC6\u5199\u4E86\uFF0C\u501F\u7528\u89C6\u9891\u6559\u7A0B",(0,r.jsx)(n.a,{href:"https://www.bilibili.com/video/BV1Kh411r7uR?p=36",children:"\u5FD7\u8FDC 2021 \u5168\u65B0 js \u9006\u5411 RPC"})]}),"\n",(0,r.jsxs)(n.p,{children:["\u901A\u8FC7\u5173\u952E\u8BCD",(0,r.jsx)(n.code,{children:"password:"})," \u4FBF\u53EF\u627E\u5230\u5BF9\u5E94\u7684\u52A0\u5BC6\u5730\u70B9\uFF0C\u627E\u5230\u52A0\u5BC6\u8C03\u7528\u7684\u51FD\u6570\u6240\u51FA\u73B0\u7684\u4F4D\u7F6E\uFF08loginv5.js 8944 \u884C\uFF09\uFF0C\u53D1\u73B0\u901A\u8FC7\u8C03\u7528",(0,r.jsx)(n.code,{children:"e.RSA.encrypt(s)"}),"\uFF08\u5176\u4E2D s \u4E3A\u660E\u6587 ",(0,r.jsx)(n.code,{children:"a123456"}),"\uFF09\uFF0C\u4FBF\u53EF\u5F97\u5230\u52A0\u5BC6\u540E\u7684\u7ED3\u679C\u3002"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008042148653.png",alt:"20211008042148653"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008041300534.png",alt:"20211008041300534"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"e.RSA.encrypt(s)\n'Zhge9q9jkiMA0UTfHxwNeyafnuUG8rcAh/gKfQpZiOQq8EYI/tJO83lKr52c4Im3cew3wVcINf2jEGEqH5EimnMI3g6eOjcdqduGyqynA4JjMJ0wltGdL8VUTTJsknsHUQlJXHOm/7zqx4NaBvOzhWzdDBk5cAOJ2DXgPaqoygg='\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\u6309\u7167\u5F80\u5E38\u7684\u505A\u6CD5\uFF0C\u9700\u8981\u5C06",(0,r.jsx)(n.code,{children:"e.RSA.encrypt(s)"}),"\u6240\u7528\u7684\u4EE3\u7801\u5904\u5355\u72EC\u62A0\u51FA\u6765\uFF0C\u653E\u5728 V8 \u5F15\u64CE\u4E0A\u6D4B\u8BD5\u6216\u4F7F\u7528\u73B0\u6709\u7684\u52A0\u5BC6\u5E93 \u5982 CryptoJS\uFF0C\u627E\u5230\u5BF9\u5E94\u7684\u5BC6\u94A5\u6765\u8FDB\u884C\u52A0\u5BC6\u3002\u4E0D\u8FC7\u8FD9\u91CC\u4F7F\u7528 RPC \u6765\u5B9E\u73B0\u8BE5\u7B97\u6CD5\u7684\u8C03\u7528\u3002"]}),"\n",(0,r.jsx)(n.h2,{id:"\u5B9E\u73B0",children:"\u5B9E\u73B0"}),"\n",(0,r.jsxs)(n.p,{children:["\u76EE\u524D\u8C03\u7528\u7684\u73AF\u5883\u6709\u4E86\uFF08\u6D4F\u89C8\u5668\u73AF\u5883\uFF09\uFF0C\u53EA\u8981\u6211\u4EEC\u8FD9\u4E2A\u6D4F\u89C8\u5668\u4E0D\u50
15C\u6B62\uFF08\u4F7F\u7528\u65E0\u5934\u6D4F\u89C8\u5668\u8FD0\u884C\uFF09\uFF0C\u63A7\u5236\u53F0\u4FBF\u80FD\u4E00\u76F4\u8F93\u51FA\u6211\u4EEC\u60F3\u8981\u7684\u52A0\u5BC6\u540E\u7ED3\u679C\u3002\u6240\u4EE5\u8981\u5B9E\u73B0\u7684\u76EE\u7684\u5F88\u7B80\u5355\uFF0C\u5C31\u662F\u5176\u4ED6\u7A97\u53E3\uFF08\u6307\u5176\u4ED6\u8BED\u8A00\u6240\u5B9E\u73B0\u7684\u7A0B\u5E8F\uFF09\uFF0C\u80FD\u8FDC\u7A0B\u8C03\u7528",(0,r.jsx)(n.code,{children:"e.RSA.encrypt(s)"}),"\u5E76\u5C06\u7ED3\u679C\u8F93\u51FA\u5230\u5176\u4ED6\u7A97\u53E3\u3002"]}),"\n",(0,r.jsx)(n.p,{children:"\u90A3\u4E48\u5C31\u9700\u8981\u5EFA\u7ACB\u901A\u4FE1\u534F\u8BAE\u4E86\uFF0C\u8FD9\u91CC\u6211\u6240\u91C7\u7528\u7684\u662F\u6D4F\u89C8\u5668\u81EA\u5E26\u7684 Websocket \u5BA2\u6237\u7AEF\u4E0E Nodejs \u642D\u5EFA\u7684 Websocket \u670D\u52A1\u7AEF\u6765\u8FDB\u884C\u901A\u4FE1\uFF0C\u4F17\u6240\u5468\u77E5 HTTP \u8BF7\u6C42\u662F\u65E0\u6CD5\u53CC\u5411\u4F20\u8F93\u7684\u3002\u6240\u4EE5\u4F7F\u7528 websocket \u8FD9\u6837\u670D\u52A1\u7AEF\u5C31\u53EF\u4EE5\u4E3B\u52A8\u5411\u6D4F\u89C8\u5668\u53D1\u9001\u8BF7\u6C42\uFF0C\u540C\u65F6 websocket \u5728\u5F53\u524D\u8FD9\u4E2A\u73AF\u5883\u4E0B\u597D\u5B9E\u73B0\u3002"}),"\n",(0,r.jsx)(n.h3,{id:"nodejs-\u5B9E\u73B0-websocket-\u670D\u52A1\u7AEF",children:"Nodejs \u5B9E\u73B0 Websocket \u670D\u52A1\u7AEF"}),"\n",(0,r.jsx)(n.h4,{id:"\u5B89\u88C5-ws-\u6A21\u5757",children:"\u5B89\u88C5 ws \u6A21\u5757"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm install ws -S\nnpm install @types/ws -D\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\u8FD9\u91CC\u4E4B\u6240\u4EE5\u9009 ws\uFF0C\u662F\u56E0\u4E3A ws \u5BF9\u4E8E Websocket \u534F\u8BAE\u800C\u5DF2\uFF0C\u5B9E\u73B0\u65B9\u4FBF\uFF0C\u4E14\u901F\u5EA6\u6700\u5FEB\uFF0C\u5E76\u4E14\u6D4F\u89C8\u5668\u53EF\u4EE5\u901A\u8FC7",(0,r.jsx)(n.code,{children:"let ws = new Websocket()"}),"\u6765\u521B\u5EFA\u5BA2\u6237\u7AEF\u76F4\u63A5\u8FDE\u63A5\uFF0C\u800C\u4F7F\u7528 socket.io \u7684\u8BDD\uFF0C\u6D4F\u89C8\u5668\u5219\u9700\u8981\u8F7D\u5165 socket.io \u5BA2\u6237\u7AEF\u6587\u4EF6\uFF0C\u7E4
11\u7410\u3002"]}),"\n",(0,r.jsx)(n.h4,{id:"\u4EE3\u7801\u4F8B\u5B50",children:"\u4EE3\u7801\u4F8B\u5B50"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="server.js"',children:"import WebSocket, { WebSocketServer } from 'ws'\n\nlet ws = new WebSocketServer({\n  port: 8080,\n})\n\nws.on('connection', socket => {\n  function message(msg) {\n    console.log('\u63A5\u53D7\u5230\u7684msg: ' + msg)\n    socket.send('\u6211\u63A5\u53D7\u5230\u4F60\u7684\u6570\u636E: ' + msg)\n  }\n\n  socket.on('message', message)\n})\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\u4F7F\u7528 WebSocket \u5728\u7EBF\u6D4B\u8BD5\u7F51\u7AD9",(0,r.jsx)(n.a,{href:"http://www.websocket-test.com/",children:"websocket \u5728\u7EBF\u6D4B\u8BD5 (websocket-test.com)"})]}),"\n",(0,r.jsx)(n.p,{children:"\u6D4B\u8BD5\u7ED3\u679C\u5982\u4E0B"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008043925753.png",alt:"20211008043925753"})}),"\n",(0,r.jsx)(n.p,{children:"\u4E0A\u9762\u4EE3\u7801\u5199\u7684\u5F88\u7B80\u964B\uFF0C\u5C24\u5176\u662F\u6570\u636E\u4EA4\u4E92\u7684\u5730\u65B9\uFF0C\u8FD9\u91CC\u53EF\u4EE5\u4F7F\u7528 json \u6765\u6539\u8FDB\u4E00\u4E0B\u3002\u50CF\u8FD9\u6837\uFF0C\u81F3\u4E8E\u4E3A\u5565\u7528 try \u662F\u9632\u6B62 json \u6570\u636E\u4E0D\u5BF9\u5BFC\u81F4\u89E3\u6790\u9519\u8BEF\uFF08\u5177\u4F53\u4EE3\u7801\u5C31\u4E0D\u89E3\u8BFB\u4E86\uFF09"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="server.js"',children:"import WebSocket, { WebSocketServer } from 'ws'\n\nlet ws = new WebSocketServer({ port: 8080 })\n\nws.on('connection', socket => {\n  console.log('\u6709\u4EBA\u8FDE\u63A5\u4E86')\n  function message(data) {\n    try {\n      let json = JSON.parse(data) // data: {\"type\":\"callbackPasswordEnc\",\"value\":\"a123456\"}\n      let { type, value } = json\n      switch (type) {\n        case 'callbackPasswordEnc':\n          // doSomething()\n          console.log('\u5F97\u5230\u7684\u52A0\u5BC6\u5BC6\u6587\u4E3A:' + value)\n          break\n      }\n    } catch (error) {\n      console.error(error)\n    }\n  }\n\n  socket.on('message', message)\n\n  // \u6D4F\u89C8\u5668\u901A\u4FE11\u79D2\u540E\u5411\u6D4F\u89C8\u5668\u8C03\u7528\u52A0\u5BC6\u7B97\u6CD5\n  setTimeout(() => {\n    let jsonStr = JSON.stringify({\n      type: 'getPasswordEnc',\n      value: 'a123456',\n    })\n    socket.send(jsonStr)\n  }, 1000)\n})\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\u6D4F\u89C8\u5668\u5B9E\u73B0-websocket",children:"\u6D4F\u89C8\u5668\u5B9E\u73B0 websocket"}),"\n",(0,r.jsx)(n.p,{children:"\u65E2\u7136\u8981\u5B9E\u73B0\u6211\u4EEC\u7684\u4EE3\u7801\uFF0C\u90A3\u4E48\u5C31\u9700\u8981\u5C06\u6211\u4EEC\u7684\u4EE3\u7801\u6CE8\u5165\u5230\u539F\u6765\u7684\u4EE3\u7801\u4E0A\uFF0C\u8FD9\u91CC\u6211\u4F7F\u7528\u7684\u662F Chrome \u7684\u5F00\u53D1\u8005\u5DE5\u5177\u4E2D\u7684\u8986\u76D6\u529F\u80FD\uFF0C\u9009\u62E9\u4E00\u4E2A\u672C\u5730\u6587\u4EF6\u5939\uFF0C\u5E76\u5141\u8BB8\u6743\u9650\u3002"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008054918531.png",alt:"20211008054918531"})}),"\n",(0,r.jsx)(n.p,{children:"\u9009\u62E9\u8981\u66FF\u6362\u4EE3\u7801\u7684\u6587\u4EF6\uFF0C\u9009\u62E9\u4FDD\u5B58\u4EE5\u5907\u66FF\u6362\uFF08\u524D\u63D0\u5F97\u5F00\u542F\u8986\u76D6\uFF09"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008055032125.png",alt:"20211008055032125"})}),"\n",(0,r.jsx)(n.p,{children:"\u63A5\u7740\u5728\u8986\u76D6\u4E2D\u627E\u5230\u6587\u4EF6\uFF0C\u627E\u5230\u52A0\u5BC6\u7684\u4EE3\u7801\u5757\uFF0C\u6DFB\u52A0\u5982\u4E0B\u4EE3\u7801"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="browser.js"',children:"!(function () {\n  let url = 'ws://127.0.0.1:8080'\n  let ws = new WebSocket(url)\n\n  // \u6D4F\u89C8\u5668\u8FDE\u63A5\u540E\u544A\u8BC9\u670D\u52A1\u7AEF\u662F\u6D4F\u89C8\u5668\n  ws.onopen = function (event) {\n    ws.send(JSON.stringify({ type: 'isBrowser', value: true }))\n  }\n\n  ws.onmessage = function (event) {\n    let json = JSON.parse(event.data)\n    let { type, value } = json\n    switch (type) {\n      case 'getPasswordEnc':\n        let passwordEnc = e.RSA.encrypt(value)\n        let jsonStr = JSON.stringify({\n          type: 'callbackPasswordEnc',\n          value: passwordEnc,\n        })\n        console.log(jsonStr)\n        ws.send(jsonStr)\n        break\n    }\n  }\n})()\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008201809446.png",alt:"20211008201809446"})}),"\n",(0,r.jsxs)(n.p,{children:["\u7136\u540E\u5C31\u662F\u6700\u5173\u952E\u7684\u5730\u65B9\u4E86\uFF0C\u89E6\u53D1\u52A0\u5BC6\u51FD\u6570\uFF0C\u5E76\u5C06\u7ED3\u679C\u8FD4\u56DE\u3002\u89E6\u53D1\u52A0\u5BC6\u51FD\u6570\u53EA\u9700\u8981\u5411\u6D4F\u89C8\u5668\u53D1\u9001\u6307\u5B9A\u6570\u636E",(0,r.jsx)(n.code,{children:'{"type":"getPasswordEnc","value":"a123456"}'}),"\uFF0C\u6D4F\u89C8\u5668\u63A5\u53D7\u5230\u5BF9\u5E94\u7684\u7C7B\u578B\u4E0E\u6570\u636E\uFF0C\u4FBF\u8C03\u7528\u76F8\u5E94\u7684\u51FD\u6570\uFF0C\u5E76\u5C06\u7ED3\u679C",(0,r.jsx)(n.code,{children:'{"type":"callbackPasswordEnc","value":"FM6SK3XiL5X0RF9NZi7qhIsu7Pd46mfKnn6YkWUNSGrJO+XXhiXyoG8huaqQW4BnmYuo0JVVQj28C+BK/r6NTNbLcV4gMSREB2hYU/oIYedCJsZ9sbZQ89p1aI9kVcDeRlX
1BhjNUxkcS9Rh+vKzyNApwpbPcAuGTCSZhKst8vVo="}'}),"\u8FD4\u56DE\u5373\u53EF\u3002"]}),"\n",(0,r.jsx)(n.p,{children:"\u670D\u52A1\u7AEF\u7684\u6548\u679C\u5982\u4E0B\u56FE"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211008204247104.png",alt:"20211008204247104"})}),"\n",(0,r.jsx)(n.h2,{id:"\u4F18\u5316\u6267\u884C\u6D41\u7A0B",children:"\u4F18\u5316\u6267\u884C\u6D41\u7A0B"}),"\n",(0,r.jsx)(n.p,{children:"\u5B9E\u73B0\u662F\u5B9E\u73B0\u4E86\uFF0C\u4F46\u662F\u4EE3\u7801\u8C8C\u4F3C\u5F88\u4E0D\u4F18\u96C5\uFF0C\u751A\u81F3\u6709\u70B9\u522B\u626D\u3002\u6309\u7406\u6765\u8BF4\u56E0\u4E3A\u662F\u6D4F\u89C8\u5668\u4F5C\u4E3A websocket \u670D\u52A1\u7AEF\uFF0C\u6211\u4EEC\u4F5C\u4E3A\u5BA2\u6237\u7AEF\uFF0C\u5BA2\u6237\u7AEF\u5411\u670D\u52A1\u5668\u83B7\u53D6\u6570\u636E\u624D\u5408\u7406\uFF0C\u4F46\u5728\u8FD9\u91CC\u6D4F\u89C8\u5668\u5F53\u4E0D\u4E86 websocket \u670D\u52A1\u7AEF\u8FD9\u4E2A\u89D2\u8272\uFF0C\u6240\u4EE5\u53EA\u80FD\u4F7F\u7528\u5982\u6B64\u522B\u626D\u7684\u65B9\u5F0F\u6765\u8C03\u7528\u3002\u50CF\u4E0A\u9762\u4F8B\u5B50\u7684\u8BDD\uFF0C\u5982\u679C\u6211\u7684\u7A0B\u5E8F\u8981\u5B9E\u73B0\u4E00\u4E2A\u67D0\u5EA6\u767B\u5F55\u7684\u8BDD\uFF0C\u90A3\u4E48\u6211\u8FD9\u4E2A\u7A0B\u5E8F\u5C31\u9700\u8981\u642D\u5EFA\u4E00\u4E2A ws \u670D\u52A1\u5668\u6765\u8FDB\u884C\u4E24\u8005\u7684\u901A\u4FE1\uFF0C\u6709\u6CA1\u6709\u597D\u7684\u529E\u6CD5\u53C8\u4E0D\u592A\u4F9D\u8D56\u4E8E ws \u670D\u52A1\u7AEF\uFF0C\u5C31\u50CF http \u90A3\u6837\uFF0C\u7A0B\u5E8F\u53EA\u9700\u8981\u53D1\u9001\u4E00\u4E2A\u8BF7\u6C42\uFF0C\u7ED9\u5B9A\u7C7B\u578B\u548C\u6570\u503C\u8FDB\u884C\u52A0\u5BC6\u5904\u7406\u540E\u8FD4\u56DE\u5373\u53EF\u3002\u4E8E\u662F\u6211\u5904\u7406\u7684\u601D\u8DEF\u662F\u8FD9\u6837\u7684\u3002"}),"\n",(0,r.jsx)(n.h2,{id:"\u601D\u8DEF",children:"\u601D\u8DEF"}),"\n",(0,r.jsx)(n.p,{children:"\u6211\u7684\u505A\u6CD5\u662F\u5C06 websocket \u670D\u52A1\u7AEF\u5F53\u4E2A\u4E2D\u8F6C\u7AD9\uFF0C\u800C\u6D4F\u89C8\u5668\u7684 websocket \u5BA2\u6237\u7AEF\u4F5C\u4E3A\u4E00\u4E2A\u52A0\u5BC6\u7B97\u6CD5\u7684\u670D\u52A1\uFF0C\u518D\u6DFB\u52A0\u4E00\u4E2A\u767B\u5F55\u7B97\u6CD5\u5B9E\u73B0\u7684\u5BA2\u6237\u7AEF\u7B80\u79F0\u4E3A\u7528\u6237\u8C03\u7528\u7684\uFF0C\u6240\u4EE5\u73B0\u5728\u4E00\u5171\u6709\u4E09\u4EFD\u4EE3\u7801\uFF08websocket \u670D\u52A1\u7AEF\uFF0C\u6D4F\u89C8\u5668\u7AEF\uFF0C\u7528\u6237\u8C03\u7528\u7AEF\uFF09\u3002\u8FD9\u91CC\u6211\u8FD8\u662F\u4EE5 nodejs \u4E3A\u4F8B\u3002"}),"\n",(0,r.jsx)(n.h3,{id:"\u6D4F\u89C8\u5668\u7AEF",children:"\u6D4F\u89C8\u5668\u7AEF"}),"\n",(0,r.jsx)(n.p,{children:"\u6D4F\u89C8\u5668 websocket \u5BA2\u6237\u7AEF\u7684\u4EE3\u7801\uFF0C\u5728\u521D\u6B21\u8FDE\u63A5\u7684\u65F6\u5019\uFF0C\u544A\u8BC9 websocket \u670D\u52A1\u7AEF\u662F\u4E0D\u662F\u6D4F\u89C8\u5668\u3002\u5E76\u5C06\u4E8E\u6D4F\u89C8\u5668\u8FDE\u63A5\u7684 socket \u53E5\u67C4\u5B58\u5165\u5168\u5C40\u5BF9\u8C61\uFF0C\u4EE5\u4FBF\u7528\u6237\u83B7\u53D6\u52A0\u5BC6\u53C2\u6570\u7684\u65F6\u5019\u5411\u6D4F\u89C8\u5668\u8C03\u7528\u3002"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="browser.js"',children:"ws.onopen = function (event) {\n  ws.send(JSON.stringify({ type: 'isBrowser', value: true }))\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\u7528\u6237\u8C03\u7528\u7AEF",children:"\u7528\u6237\u8C03\u7528\u7AEF"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="client.js"',children:"import WebSocket from 'ws'\n\nasync function getPasswordEnc(password) {\n  return new Promise((resolve, reject) => {\n    const ws = new WebSocket('ws://127.0.0.1:8080')\n\n    ws.on('open', () => {\n      let jsonStr = JSON.stringify({\n        type: 'getPasswordEnc',\n        value: password,\n      })\n      ws.send(jsonStr)\n    })\n\n    ws.on('message', message => {\n      let json = JSON.parse(message)\n      let { type, value } = json\n      switch (type) {\n        case 'callbackPasswordEnc':\n          ws.close()\n          resolve(value)\n          break\n      }\n    })\n  })\n}\n\nasync function run() {\n  let passwordEnc = await getPasswordEnc('a123456')\n  console.log(passwordEnc)\n}\n\nrun()\n"})}),"\n",(0,r.jsx)(n.p,{children:"\u8FD9\u91CC\u5BF9\u4EE3\u7801\u8FDB\u884C\u89E3\u8BFB\u4E00\u4E0B\uFF0C\u6211\u81EA\u884C\u5C01\u88C5\u4E86\u4E00\u4E2A\u51FD\u6570\uFF0C\u5176\u4E2D\u51FD\u6570\u8FD4\u56DE\u7684\u662F\u4
1E00\u4E2A Promise \u5BF9\u8C61\uFF0C\u503C\u5219\u662F\u5BF9\u5E94\u7684\u52A0\u5BC6\u540E\u7684\u5BC6\u6587\u3002\u5982\u679C\u6211\u8FD9\u8FB9\u4E0D\u91C7\u7528 promise \u6765\u7F16\u5199\u7684\u8BDD\uFF0C\u90A3\u4E48\u83B7\u53D6\u5230\u7684\u6570\u636E\u5C06\u5341\u5206\u4E0D\u597D\u8FD4\u56DE\u7ED9\u6211\u4EEC\u7684\u4E3B\u7EBF\u7A0B\u3002\u8FD9\u91CC\u5BF9\u4E8E js \u7684 Promise \u4F7F\u7528\u9700\u8981\u82B1\u8D39\u70B9\u65F6\u95F4\u53BB\u7406\u89E3\u3002\u603B\u800C\u8A00\u4E4B\uFF0C\u901A\u8FC7 promise\uFF0C\u4EE5\u53CA async await \u8BED\u6CD5\u7CD6\uFF0C\u80FD\u5F88\u8F7B\u677E\u7684\u7B49\u5F85 websocket \u8FDE\u63A5\u4E0E\u63A5\u6536\u6570\u636E\u3002\u4F46\u8FD8\u662F\u7528 websocket \u534F\u8BAE"}),"\n",(0,r.jsx)(n.h3,{id:"websocket-\u670D\u52A1\u7AEF",children:"websocket \u670D\u52A1\u7AEF"}),"\n",(0,r.jsx)(n.p,{children:"\u540C\u65F6 websocket \u670D\u52A1\u7AEF\u80AF\u5B9A\u8981\u65B0\u589E\u4E00\u4E2A\u7C7B\u578B\u7528\u4E8E\u5224\u65AD\u662F\u767B\u5F55\u7B97\u6CD5\u5B9E\u73B0\u7684\u5BA2\u6237\u7AEF\u3002\u540C\u65F6\u53C8\u65B0\u7684\u7528\u6237\u8981\u8C03\u7528\uFF0C\u6240\u4EE5\u8FD9\u91CC\u4F7F\u7528\u4E86 uuid \u8FD9\u4E2A\u6A21\u5757\u6765\u751F\u6210\u552F\u4E00\u7684\u7528\u6237 id\uFF0C\u540C\u65F6\u8FD8\u5B9A\u4E49\u4E00\u4E2A\u53D8\u91CF clients \u8BB0\u5F55\u6240\u8FDE\u63A5\u8FC7\u7684\u7528\u6237\uFF08\u5305\u62EC\u6D4F\u89C8\u5668\uFF09\uFF0C\u5B8C\u6574\u4EE3\u7801\u5982\u4E0B"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="server.js"',children:"import WebSocket, { WebSocketServer } from 'ws'\nimport { v4 as uuidv4 } from 'uuid'\n\nlet ws = new WebSocketServer({ port: 8080 })\n\nlet browserWebsocket = null\nlet clients = []\n\nws.on('connection', socket => {\n  let client_id = uuidv4()\n  clients.push({\n    id: client_id,\n    socket: socket,\n  })\n\n  socket.on('close', () => {\n    for (let i = 0; i < clients.length; i++) {\n      if (clients[i].id == client_id) {\n        clients.splice(i, 1)\n        break\n      }\n    }\n  })\n\n  socket.on('message', message => {\n    try {\n      let json = JSON.parse(message)\n      let { id, type, value } = json\n      switch (type) {\n        case 'isBrowser':\n          if (value) {\n            browserWebsocket = socket\n          }\n          console.log('\u6D4F\u89C8\u5668\u5DF2\u521D\u59CB\u5316')\n          break\n\n        // \u53D1\u9001\u7ED9\u6D4F\u89C8\u5668 \u8BA9\u6D4F\u89C8\u5668\u6765\u8C03\u7528\u5E76\u8FD4\u56DE\n        case 'callbackPasswordEnc':\n          // \u6839\u636Eid\u627E\u5230\u8C03\u7528\u7528\u6237\u7684socket,\u5E76\u5411\u8BE5\u7528\u6237\u53D1\u9001\u52A0\u5BC6\u540E\u7684\u5BC6\u6587\n          let temp_socket = clients.find(c => c.id == id).socket\n\n          temp_socket.send(message)\n          break\n        // \u7528\u6237\u53D1\u9001\u8FC7\u6765\u8981\u52A0\u5BC6\u7684\u660E\u6587\n        case 'getPasswordEnc':\n          let jsonStr = JSON.stringify({\n            id: client_id,\n            type: type,\n            value: value,\n          })\n\n          // \u8FD9\u91CC\u4E00\u5B9A\u8981\u662F\u6D4F\u89C8\u5668\u7684websocket\u53E5\u67C4\u53D1\u9001\uFF0C\u624D\u80FD\u8C03\u7528\n          browserWebsocket.send(jsonStr)\n          break\n      }\n    } catch (error) {\n      console.log(error.message)\n    }\n  })\n})\n"})}),"\n",(0,r.jsx)(n.p,{children:"\u6700\u7EC8\u6F14\u793A\u6548\u679C\u5982\u4E0B\u89C6\u9891\uFF08\u6D4F\u89C8\u5668\u4EE3\u7801\u662F\u63D0\u524D\u6CE8\u5165\u8FDB\u53BB\u7684\uFF09"}),"\n",(0,r.jsx)("video",{width:"800px",height:"450px",controls:"controls",children:(0,r.jsx)("source",{id:"mp4",src:"https://img.kuizuo.me/rpc.mp4",type:"video/mp4"})}),"\n",(0,r.jsx)(n.p,{children:"\u5176\u5B9E\u8FD8\u662F\u4E00\u4E9B\u662F\u8981\u5B8C\u5584\u7684\uFF0C\u8FD9\u91CC\u7684 Websocket \u53EA\u662F\u5B9E\u73B0\u4E86\u8FDE\u63A5\uFF0C\u8FD8\u6709\u5FC3\u8DF3\u5305\u5F02\u5E38\u65AD\u5F00\uFF0C\u6D4F\u89C8\u5668\u5F02\u5E38\u5173\u95ED\u5BFC\u81F4 websocket \u65AD\u5F00\u65E0\u6CD5\u8C03\u7528\u51FD\u6570\u7B49\u7B49\uFF0C\u4EE5\u53CA\u6D4F\u89C8\u5668\u7684\u4EE3\u7801\u8FD8\u9700\u8981\u624B\u52A8\u6CE8\u5165\u5F88\u4E0D\u4F18\u5316\uFF0C\u540E\u7EED\u5982\u679C\u4F7F\u7528 Chrome \u63D2\u4EF6\u5F00\u53D1\u4E00\u4E2A\u5B9E\u73B0\u6CE8\u5165 js \u4EE3\u7801\u7684\u529F\u80FD\u4E5F\u8BB8\u4F1A\u597D\u4E00\u4E9B\u3002\uFF08\u6B63\u51C6\u5907\u7F16\u5199 Chrome \u63D2\u4EF6\uFF09"}),"\n",(0,r.jsx)(n.h2,{id:"http-\u534F\u8BAE\u8C03\u7528\u5B9E\u73B0",children:"HTTP \u534F\u8BAE\u8C03\u7528\u5B9E\u73B0"}),"\n",(0,r.jsx)(n.p,{children:"\u4F46\u662F\uFF0C\u4EE5\u4E0A\u90FD\u662F\u57FA\u4E8E WebSocket \u534F\u8BAE\uFF0C\u5C31\u8FDE\u7528\u6237\u7AEF\u8C03\u7528\u4E5F\u662F\uFF0C\u7136\u800C\u7528\u6237\u8C03\u7528\u6CA1\u5FC5\u8981\u4FDD\u6301\u957F\u8FDE\u63A5\u4E14\u4E0D\u5229\u4E8E\u8C03\u7528\uFF08\u76F8\u5BF9\u4E00\u4E9B\u8BED\u8A00\u800C\u8A00\uFF09\uFF0C\u6709\u6CA1\u6709\u80FD\u76F4\u63A5\u4F7F\u7528 http \u534F\u8BAE\uFF0C\u901A\u8FC7 POST \u8BF7\u6C42\u6765\u5B9E\u73B0\u83B7\u53D6\u53C2\u6570\uFF0C\u8FD9\u624D\u662F\u6211\u6240\u8981\u5B9E\u73B0\u7684\u3002"}),"\n",(0,r.jsxs)(n.p,{children:["\u5176\u5B9E\u8981\u5B9E\u73B0\u4E5F\u5F88\u7B80\u5355\uFF0C\u6211\u53EA\u8981\u628A\u7528\u6237\u8C03\u7528\u7684 ",(0,r.jsx)(n.code,{children:"getPasswordEnc"})," \u8FD9\u4E2A\u51FD\u6570 \u5F04\u5230 node \u521B\u5EFA\u7684\u4E00\u4E2A http \u670D\u52A1\u7AEF\u5C31\u884C\u4E86\uFF0C\u6211\u8FD9\u91CC\u7684\u505A\u6CD5\u4E5F\u662F\u5982\u6B64\u3002\u50CF\u4E0B\u9762\u8FD9\u6837"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",metastring:'title="server_http.js"',children:"async function getPasswordEnc(password) {\n  return new Promise((resolve, reject) => {\n    const ws = new WebSocket('ws://127.0.0.1:8080')\n\n    ws.on('open', () => {\n      let jsonStr = JSON.stringify({\n        type: 'getPasswordEnc',\n        value: password,\n      })\n      ws.send(jsonStr)\n    })\n\n    ws.on('message', message => {\n      let json = JSON.parse(message)\n      let { type, value } = json\n      switch (type) {\n        case 'callbackPasswordEnc':\n          ws.close()\n          resolve(value)\n          break\n      }\n    })\n  })\n}\n\n// \u521B\u5EFAhttp\u670D\u52A1\nconst app = http.createServer(async (request, response) => {\n  let { pathname, query } = url.parse(request.url, true)\n\n  if (pathname == '/getPasswordEnc') {\n    let passwordEnc = await getPasswordEnc(query.password)\n    response.end(passwordEnc)\n  }\n})\n\napp.listen(8000, () => {\n  console.log(`\u670D\u52A1\u5DF2\u8FD0\u884C http://127.0.0.1:8000/`)\n})\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\u53D1\u9001 GET \u8BF7\u6C42 URL \u4E3A ",(0,r.jsx)(n.a,{href:"http://127.0.0.1:8000/getPasswordEnc?password=a123456",children:"http://127.0.0.1:8000/getPasswordEnc?password=a123456"})," \u5B9E\u73B0\u6548\u679C\u5982\u56FE"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{src:"https://img.kuizuo.me/20211009040704534.png",alt:"20211009040704534"})}),"\n",(0,r.jsx)(n.p,{children:"\u5BF9\u4E8E\u7528\u6237\u8C03\u7528\u6765\u8BF4\u76F8\u5BF9\u53CB\u597D\u4E86\u4E0D\u5C11\uFF08\u5176\u5B9E\u662F\u5F88\u597D\uFF09\uFF0C\u4E0D\u7528\u5728\u521B\u5EFA websocket \u5BA2\u6237\u7AEF\uFF0C\u53EA\u9700\u8981\u53D1\u9001 HTTP \u8BF7\u6C42\uFF08GET \u6216 POST\uFF09\uFF0C\u4E0D\u8FC7\u6211\u8FD9\u8FB9\u4F7F\u7528\u7684\u662F Node \u81EA\u5E26\u7684 http \u6A21\u5757\u6765\u642D\u5EFA\u7684\u4E00\u4E2A http \u670D\u52A1\u5668\uFF0C\u5B9E\u9645\u4F7F\u7528\u4E2D\u5C06\u4F1A\u91C7\u7528 express \u6765\u7F16\u5199\u8DEF\u7531\u63D0\u9AD8\u5F00\u53D1\u6548\u7387\u548C\u4EE3\u7801\u53EF\u8BFB\u6027\uFF0C\u8FD9\u91CC\u53EA\u662F\u4F5C\u4E3A\u6F14\u793A\u3002"}),"\n",(0,r.jsx)(n.p,{children:"\u81F3\u4E8E\u8BF4\u6211\u4E3A\u4EC0\u4E48\u8981\u5728 http \u5185\u5728\u65B0\u5EFA\u4E00\u4E2A ws \u5BA2\u6237\u7AEF\uFF0C\u4E3B\u8981\u539F\u56E0\u8FD8\u662F websocket \u670D\u52A1\u7AEF\u5411\u6D4F\u89C8\u5668\u53D1\u9001\u8C03\u7528\u7684\u7B97\u6CD5\uFF0C\u4F46\u53EA\u80FD\u5728 websocket \u670D\u52A1\u7AEF\u4E2D\u7684\u901A\u8FC7 onmessage \u63A5\u53D7\uFF0C\u65E0\u6CD5\u5728 http \u670D\u52A1\u7AEF\u63A5\u53D7\u5230\uFF0C\u5C31\u522B\u8BF4\u5411\u7528\u6237\u7AEF\u8FD4\u56DE\u4E86\u3002\u8FD9\u91CC\u5176\u5B9E\u53EA\u662F\u4
1E0D\u8BA9\u7528\u6237\u6765\u8FDB\u884C\u8FDE\u63A5 websocket\uFF0C\u800C\u662F\u6211\u4EEC\u672C\u5730\uFF08\u670D\u52A1\u5668\uFF09\u5728\u63A5\u53D7\u5230 getPasswordEnc \u8BF7\u6C42\uFF0C\u590D\u73B0\u4E86\u4E00\u904D\u4E0A\u9762\u7528\u6237\u8FDE\u63A5 websocket \u7684\u4F8B\u5B50\uFF0C\u5E76\u5C06\u5176\u8F6C\u4E3A http \u8BF7\u6C42\u8FD4\u56DE\u7ED9\u7528\u6237\u800C\u5DF2\u3002"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\u5176\u5B9E\u4E5F\u5C31\u662F\u591A\u4E86\u4E00\u4E2A\u8C03\u7528\u7684 HTTP \u670D\u52A1\u5668\uFF0C\u800C\u8FD9\u91CC\u5C06 http \u670D\u52A1\u5668\u4E0E websocket \u670D\u52A1\u5668\u5199\u5230\u4E00\u8D77\u800C\u5DF2"})}),"\n",(0,r.jsx)(n.h2,{id:"\u4EE3\u7801\u5730\u5740",children:"\u4EE3\u7801\u5730\u5740"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://github.com/kuizuo/rpc-browser.git",children:"https://github.com/kuizuo/rpc-browser.git"})}),"\n",(0,r.jsx)(n.p,{children:"\u8FD0\u884C\u65B9\u5F0F\u8BF7\u67E5\u770B README.md"})]})}function p(e={}){let{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},89999(e,n,s){s.d(n,{R:()=>c,x:()=>l});var t=s(58101);let r={},o=t.createContext(r);function c(e){let n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(o.Provider,{value:n},e.children)}},20999(e){e.exports=JSON.parse('{"permalink":"/blog/remote-call-browser-function","editUrl":"https://github.com/kuizuo/blog/edit/main/blog/develop/RPC\u8FDC\u7A0B\u8C03\u7528\u6D4F\u89C8\u5668\u51FD\u6570.md","source":"@site/blog/develop/RPC\u8FDC\u7A0B\u8C03\u7528\u6D4F\u89C8\u5668\u51FD\u6570.md","title":"RPC\u8FDC\u7A0B\u8C03\u7528\u6D4F\u89C8\u5668\u51FD\u6570","description":"\u65E9\u95FB RPC\uFF08Remote Procedure Call\uFF09\u8FDC\u7A0B\u8FC7\u7A0B\u8C03\u7528\uFF0C\u8FD9\u4E00\u8BCD\u4E86\uFF0C\u5E94\u8BE5\u662F\u5728\u5B89\u5353\u9006\u5411\u7684\u65F6\u5019\u542C\u95FB\u7684\uFF0C\u5F53\u65F6\u5439\u5618\u7684\u610F\u601D\u662F\u8FD9\u6837\u7684\uFF0C\u901A\u8FC7\u53E6\u4E00\u4E2A\u8FDC\u7AEF\u670D\u52A1\u5668\u6765\u8C03\u7528\u5B89\u5353\u4EE3\u7801\u4E2D\u7684\u51FD\u6570\uFF0C\u5E76\u5C06\u6267\u884C\u540E\u7684\u7ED3\u679C\u8FD4\u56DE\u3002\u6BD4\u5982\u6709\u4E00\u4E2A\u52A0\u5BC6\u7B97\u6CD5\uFF0C\u5982\u679C\u8981\u5B9E\u73B0\u8131\u673A\uFF08\u8131\u79BB\u5F53\u524D\u73AF\u5883\uFF09\u8FD0\u884C\u7684\u8BDD\uFF0C\u5C31\u9700\u8981\u6263\u9664\u76F8\u5BF9\u5E94\u7684\u4EE3\u7801\uFF0C\u8865\u9F50\u5BF9\u5E94\u7684\u73AF\u5883\uFF08\u6A21\u5757\uFF0C\u4E0A\u4E0B\u6587\uFF0C\u8BED\u8A00\uFF09\uFF0C\u7136\u800C\u8981\u5728\u8865\u9F50\u8BE5\u52A0\u5BC6\u7B97\u6CD5\u7684\u73AF\u5883\u53EF\u4E0D\u597D\u5B9E\u73B0\uFF0C\u800C\u901A\u8FC7 RPC \u5219\u53EF\u4EE5\u514D\u9664\u6263\u4EE3\u7801\uFF0C\u901A\u8FC7\u6570\u636E\u901A\u4FE1\u6765\u8FBE\u5230\u8FDC\u7A0B\u8C03\u7528\u7684\u76EE\u7684\uFF0C\u542C\u8D77\u6765\u662F\u633A\u725B\u903C\u7684\uFF0C\u5B9E\u9645\u4E0A\u4E5F\u786E\u5B9E\u633A\u9A9A\u7684\u3002\u8FD9\u91CC\u6211\u5C06\u4EE5\u6D4F\u89C8\u5668\u4E0E\u672C\u5730\u642D\u5EFA\u4E00\u4E2A websocket \u6765\u5B9E\u73B0\u8C03\u7528\u6D4F\u89C8\u5668\u5185\u7684\u51FD\u6570\u3002","date":"2021-10-09T00:00:00.000Z","tags":[{"inline":true,"label":"javascript","permalink":"/blog/tags/javascript"},{"inline":true,"label":"rpc","permalink":"/blog/tags/rpc"},{"inline":true,"label":"browser","permalink":"/blog/tags/browser"}],"readingTime":6.62,"hasTruncateMarker":true,"authors":[{"name":"\u6127\u600D","title":"\u5168\u6808 typescripter / \u521A\u6BD5\u4E1A\u7684\u5B66\u751F","url":"https://github.com/kuizuo","email":"[email protected]","socials":{"x":"https://x.com/kuizuo","github":"https://github.com/kuizuo"},"imageURL":"https://kuizuo.me/img/logo.png","key":"kuizuo","page":null}],"frontMatter":{"slug":"remote-call-browser-function","title":"RPC\u8FDC\u7A0B\u8C03\u7528\u6D4F\u89C8\u5668\u51FD\u6570","date":"2021-10-09T00:00:00.000Z","authors":"kuizuo","tags":["javascript","rpc","browser"],"keywords":["javascript","rpc","browser"]},"unlisted":false,"prevItem":{"title":"JS\u51FD\u6570hook","permalink":"/blog/js-function-hook"},"nextItem":{"title":"\u8BB0 ThinkPHP \u9879\u76EE\u90E8\u7F72","permalink":"/blog/thinkphp-deploy"}}')}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.