{"id":19044065,"url":"https://github.com/xxxily/broadcast-message","last_synced_at":"2025-04-23T23:26:59.705Z","repository":{"id":64354110,"uuid":"566709728","full_name":"xxxily/broadcast-message","owner":"xxxily","description":"基于postMessage+BroadcastChannel+localStorage+互信域名的前端页面数据通信解决方案","archived":false,"fork":false,"pushed_at":"2022-12-14T06:36:53.000Z","size":1210,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-14T18:54:10.342Z","etag":null,"topics":["broadcast","broadcastchannel","broadcastmessage","cross-domain","crosstab","ipc","localstorage","postmessage"],"latest_commit_sha":null,"homepage":"https://broadcast-message.anzz.top","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xxxily.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-11-16T08:55:19.000Z","updated_at":"2024-11-04T03:23:37.000Z","dependencies_parsed_at":"2023-01-15T13:15:25.500Z","dependency_job_id":null,"html_url":"https://github.com/xxxily/broadcast-message","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxxily%2Fbroadcast-message","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxxily%2Fbroadcast-message/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxxily%2Fbroadcast-message/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxxily%2Fbroadcast-message/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xxxily","download_url":"https://codeload.github.com/xxxily/broadcast-message/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250530779,"owners_count":21445852,"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":["broadcast","broadcastchannel","broadcastmessage","cross-domain","crosstab","ipc","localstorage","postmessage"],"created_at":"2024-11-08T22:44:45.095Z","updated_at":"2025-04-23T23:26:59.664Z","avatar_url":"https://github.com/xxxily.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# broadcast-message\n\n![broadcast-message](/logo.png)  \n\n\u003e 基于postMessage+BroadcastChannel+localStorage+互信域名的前端页面数据通信解决方案\n\n## 特性\n\n- 继承了BroadcastChannel通信的优点：支持跨TAB通信\n- 继承了localStorage通信的优点：兼容性好\n- 继承了postMessage通信的优点：支持跨域通信\n- 一套脚本解决前端数据通信面临的众多情况\n- 支持同页、弹窗页、父子嵌套页、跨域、跨TAB页的通信\n\n## 安装\n\n```sh\n# npm\nnpm install broadcast-message\n\n# yarn\nyarn add broadcast-message\n```\n\n中国大陆用户可使用阿里源进行加速安装\n\n```sh\n# npm\nnpm install broadcast-message --registry=https://registry.npmmirror.com\n\n# yarn\nyarn add broadcast-message --registry=https://registry.npmmirror.com\n```\n\n## 使用\n\n### 同域下基本使用示例  \n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\n\nconst bmOpts = { channelId: 'demo', allowLocalBroadcast: true }\nconst broadcastMessage = new BroadcastMessage(bmOpts)\n\n/* 注册接收消息事件 */\nbroadcastMessage.addEventListener(\"message\", event =\u003e {\n  console.log(`[BroadcastMessage-Event]`, event.data)\n})\n\n/* 发送消息 */\nbroadcastMessage.postMessage(`[demo] ${Date.now()}`)\n```\n\n### 指定使用`localStorage`来中转消息  \n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\n\nconst bmOpts = { channelId: 'localStorage-demo', allowLocalBroadcast: true, transportType: 'localStorage' }\nconst broadcastMessage = new BroadcastMessage(bmOpts)\n\n/* 注册接收消息事件 */\nbroadcastMessage.addEventListener(\"message\", function (event) {\n  console.log(`[BroadcastMessage-Event]`, event.data)\n})\n\n/* 发送消息 */\nbroadcastMessage.postMessage(`[localStorage-demo] ${Date.now()}`)\n```\n\n`PS: 一般不建议手动指定transportType类型，broadcast-message默认会根据浏览器的支持情况自动选择BroadcastChannel还是localStorage，另外你应该了解的是：BroadcastChannel的通信效率比localStorage高`\n\n### 跨域下基本使用示例  \n\n假设：  \n\n- 域名A是消息接收方  \n- 域名B是消息发送方  \n\n域名A的代码示例：\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\n\nconst bmOpts = { \n  channelId: 'cross-domain-demo', \n  \n  /* 必须使用可信域下的broadcast-message页来进行消息的中转，后面会介绍如何自定义可信域页面地址 */\n  trustedDomainPages: 'https://broadcast-message.anzz.top/dist/pages/broadcast-message.html',\n\n  /* 指定接收来自哪个域名发送过来的消息，*表示信任所有域名的消息，生产环境推荐必须指定具体域名 */\n  // targetOrigin: \"https:anzz.top\"\n  targetOrigin: \"*\"\n}\n\nconst broadcastMessage = new BroadcastMessage(bmOpts)\n\n/* 注册接收消息事件 */\nbroadcastMessage.addEventListener(\"message\", event =\u003e {\n  console.log(`[BroadcastMessage-Event]`, event.data)\n})\n```\n\n域名B的代码示例：\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\n\nconst bmOpts = {\n  channelId: 'cross-domain-demo', \n  \n  /* 可信域消息中转页的地址必须和域名A定义的一致 */\n  trustedDomainPages: 'https://broadcast-message.anzz.top/dist/pages/broadcast-message.html',\n}\nconst broadcastMessage = new BroadcastMessage(bmOpts)\n\n/* 发送消息 */\nbroadcastMessage.postMessage(`[cross-domain-demo] ${Date.now()}`)\n```\n\n附注：当进行跨域通信时，需先确认域名A和域名B的页面都已加载，且都完成了broadcast-message的初始化工作，才能开始通信，否则会出现消息发送出去了，但接收方还没准备好等情况，导致消息通信失败\n\n### 自定义可信域页面\n\n对于有跨域通信需求的项目，加载一个可信域的页面作为消息中转页是必不可少的。默认可以使用项目的自带可信域页面：  \n\u003chttps://broadcast-message.anzz.top/dist/pages/broadcast-message.html\u003e  \n\n但出于下面的原因你可能需要自定义可信域页面\n\n- 需要更快更稳定的可信域页面\n- 项目对第三方网址有严格的限定\n- 封装内部使用的跨域消息通信库\n\n自定义可信域页面代码示例如下：\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nnew BroadcastMessage({\n  /* 只需标识当前脚本运行在可信域页面内即可 */\n  inTrustedDomainPages: true,\n})\n```\n\n将初始化了`inTrustedDomainPages`选项的页面发布出去，即可获得一个自定义可信域页面  \n\n附注：为了让自定义可信域页面更快地加载，你应该务必不要掺杂其他无关逻辑进去，它只作为消息中转页面存在，并不需要其他额外内容  \n\n## broadcast-message选项\n\n`new BroadcastMessage(opts)` 中的opts是一个对象它包含的选项和具体说明如下：\n\n```javascript\nconst bmOpts = {\n  /**\n   * 指定BroadcastMessage的消息频道id，不同BroadcastMessage实例，只要channelId一致即可通信\n   * 默认的channelId为\"*\" , 这意味着在不指定频道id的情况下，各个实例的消息都会发往同一个频道上\n   */\n  channelId: '*',\n\n  /**\n   * 允许既是消息的发送页，也可以是消息的接收页，从而做到同源同页收发消息\n   * postMessage、BroadcastChannel和storage事件都是必须一个页面发送，另一个页面接收\n   * 而BroadcastMessage允许同页面收发消息，只需将allowLocalBroadcast设为true即可\n   */\n  allowLocalBroadcast: false,\n\n  /**\n   * 给 broadcastMessage.addEventListener(\"message\", function (event) {}) 事件派发原始消息对象\n   * 默认情况下，broadcastMessage.postMessage(msg) 中的 msg 等于接收到的 event.data，但其实为了能准确派送消息，\n   * msg会被包装成有很多辅助参数的对象，如果你需要这些辅助参数信息，可以将emitOriginalMessage设为true\n   * 则收到的event.data将是如下的对象实体：\n   * event.data = {\n   *    data: msg,                   // 消息本体\n   *    type: 'BroadcastMessage',    // 消息类型，默认为BroadcastMessage，其他类型，则是自定义消息或内部消息\n   *    origin: '',                  // 消息来源的域名地址\n   *    targetOrigin: '',            // 消息目标源的域名地址\n   *    referrer: '',                // 消息来自哪个页面\n   *    timeStamp: '',               // 消息发出时的时间戳\n   *    transportType: '',           // 中转消息的载体类型，只可能为BroadcastMessage和localStorage\n   *    allowLocalBroadcast: false,  // 该消息是否允许被同页面的BroadcastMessage实例接收到\n   *    channelId: '*',              // 消息所属的频道id\n   *    instanceId: 'xx_xx',         // 消息所属BroadcastMessage实例id\n   *    debug: false                 // 是否为开启了调试选项的消息\n   * }\n   */\n  emitOriginalMessage: false,\n\n  /**\n   * 指定消息发送的目标域，规则跟postMessage的targetOrigin一样\n   * 但不同的是支持定义数组形式的targetOrigin，从而实现批量跨域数据发送\n   * 当然如果是\"*\"的话就是给任意运行了本插件的页面发送数据\n   * 默认为 `location.origin`，即只可以在同域名的页面之间进行通信\n   */\n  targetOrigin: location.origin,\n\n  /**\n   * 指定数据中转传输使用的传输类型，可选值：BroadcastChannel、localStorage\n   * 不指定的话，优先使用BroadcastChannel，在不兼容BroadcastChannel的浏览器下使用localStorage\n   * 无特需情况，不建议修改该项配置\n   */\n  transportType: 'BroadcastChannel',\n\n  /**\n   * 标识BroadcastMessage实例是否处于可信域的页面上运行\n   * 如果是，当前页面作为可信域的中介页嵌入到具体运行环境中\n   * 该选项只在自定义可信域页面中使用，其他情况不要使用\n   */\n  inTrustedDomainPages: false,\n\n  /**\n   * 指定作为消息中转的可信域页面地址，有需跨域通信需求才会用到该选项\n   * 官方提供的可信域页面地址为：\n   * https://broadcast-message.anzz.top/dist/pages/broadcast-message.html\n   */\n  trustedDomainPages: '',\n\n  /* 标识是否开启调试选项 */\n  debug: false,\n}\n```\n\n## broadcast-message方法\n\nbroadcast-message实例包含的方法如下：\n\n- addEventListener\n- onMessage\n- removeEventListener\n- offMessage\n- postMessage\n- ready\n- close\n\n下面对各个函数的使用方式进行逐一说明：\n\n### addEventListener\n\n函数参数：  \n\n- type {String} 必选，必须为 'message'\n- listener {Function} 必选\n\n添加消息事件的侦听器\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\n\nbroadcastMessage.addEventListener('message', event =\u003e {\n  console.log(`[BroadcastMessage-Event]`, event.data)  \n})\n```\n\n### onMessage\n\n函数参数：  \n\n- handler {Function} 必选\n\n添加消息处理函数，addEventListener是基于onMessage的，只是为了让BroadcastMessage保持跟BroadcastChannel一致的函数调用方式，所以增加了addEventListener事件\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\n\nbroadcastMessage.onMessage(event =\u003e {\n  console.log(`[BroadcastMessage-Event]`, event.data)  \n})\n```\n\n### removeEventListener\n\n函数参数：  \n\n- type {String} 必选，必须为 'message'\n- listener {Function} 必选\n\n移除消息事件的侦听器\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\n\nconst listener = event =\u003e { console.log(`[BroadcastMessage-Event]`, event.data) }\nbroadcastMessage.addEventListener('message', listener)\n\n/* 一段时间后移除消息事件侦听器 */\nsetTimeout(() =\u003e { broadcastMessage.removeEventListener('message', listener) }, 3000)\n```\n\n### offMessage\n\n函数参数：  \n\n- handler {Function} 必选\n\n移除消息处理函数，removeEventListener是基于onMessage的，只是为了让BroadcastMessage保持跟BroadcastChannel一致的函数调用方式，所以增加了removeEventListener事件\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\n\nconst handler = event =\u003e { console.log(`[BroadcastMessage-Event]`, event.data) }\nbroadcastMessage.onMessage(handler)\n\n/* 一段时间后移除消息事件处理函数 */\nsetTimeout(() =\u003e { broadcastMessage.offMessage(listener) }, 3000)\n```\n\n### postMessage\n\n函数参数：  \n\n- message {String|Number|Array|Object} 必选，必须为 'message'\n- messageType {String} 可选 默认为'BroadcastMessage', 内部消息为：'Internal-BroadcastMessage', 一般不需传入该参数\n\n发送消息\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\nbroadcastMessage.postMessage('test')\n```\n\n### ready\n\n函数参数：  \n\n- handler {Function} 必选 BroadcastMessage实例创建就绪后的回调函数\n\n侦听BroadcastMessage实例创建就绪后，再执行响应的回调操作，因为BroadcastMessage初始化会创建消息中转的iframe，需要一定的创建时间，所以并不是拥有了BroadcastMessage实例就可以马上postMessage，而是要等到实例就绪才会将消息传送出去  \n\n默认情况下，在执行postMessage前，会自动检测BroadcastMessage实例是否完全就绪，如果没有会将需要发送的消息缓存起来，等BroadcastMessage实例创建就绪之后才将缓存的消息发送出去\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nconst broadcastMessage = new BroadcastMessage({...opts})\n\nbroadcastMessage.ready(() =\u003e {\n  broadcastMessage.postMessage('test')\n})\n\n// 如果没使用ready函数，直接调用postMessage也是没问题的\n// 这是因为BroadcastMessage会自动判断实例是否创建就绪\n// broadcastMessage.postMessage('test')\n```\n\n### close\n\n函数参数：  \n\n- 无\n\n需要销毁BroadcastMessage实例时调用的函数，该函数会将BroadcastMessage中转所需的iframe、BroadcastChannel实例和通过addEventListener或onMessage定义的消息函数销毁掉\n\n```javascript\nimport BroadcastMessage from 'broadcast-message'\nlet broadcastMessage = new BroadcastMessage({...opts})\n\nbroadcastMessage.onMessage(event =\u003e { console.log(`[BroadcastMessage-Event]`, event.data) })\nbroadcastMessage.postMessage('test')\n\n/* 一段时间后销毁broadcastMessage实例 */\nsetTimeout(() =\u003e { \n  broadcastMessage.close() \n  broadcastMessage = null\n}, 3000)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxxxily%2Fbroadcast-message","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxxxily%2Fbroadcast-message","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxxxily%2Fbroadcast-message/lists"}