{"id":13396849,"url":"https://github.com/krakenjs/post-robot","last_synced_at":"2025-04-14T05:58:58.871Z","repository":{"id":40789326,"uuid":"59850586","full_name":"krakenjs/post-robot","owner":"krakenjs","description":"Cross domain post-messaging on the client side using a simple listener/client pattern.","archived":true,"fork":false,"pushed_at":"2024-08-05T16:38:44.000Z","size":10748,"stargazers_count":759,"open_issues_count":0,"forks_count":92,"subscribers_count":25,"default_branch":"main","last_synced_at":"2025-04-14T05:18:47.247Z","etag":null,"topics":["hacktoberfest","popup","popup-messaging","popup-windows","post-messaging","postmessaging","promise"],"latest_commit_sha":null,"homepage":"","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/krakenjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS"}},"created_at":"2016-05-27T17:05:49.000Z","updated_at":"2025-04-11T13:32:13.000Z","dependencies_parsed_at":"2024-01-08T07:55:42.183Z","dependency_job_id":"840b1e59-03c2-41ff-a5c5-d6f72c9536be","html_url":"https://github.com/krakenjs/post-robot","commit_stats":{"total_commits":1018,"total_committers":24,"mean_commits":"42.416666666666664","dds":0.2848722986247544,"last_synced_commit":"30ab862e90a023531cd46d5fe8a7342c887b521b"},"previous_names":[],"tags_count":278,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fpost-robot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fpost-robot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fpost-robot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/krakenjs%2Fpost-robot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/krakenjs","download_url":"https://codeload.github.com/krakenjs/post-robot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248824693,"owners_count":21167345,"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":["hacktoberfest","popup","popup-messaging","popup-windows","post-messaging","postmessaging","promise"],"created_at":"2024-07-30T18:01:04.811Z","updated_at":"2025-04-14T05:58:58.834Z","avatar_url":"https://github.com/krakenjs.png","language":"JavaScript","funding_links":[],"categories":["Packages","JavaScript"],"sub_categories":[],"readme":"# post-robot [:]-\\\\-\u003c\n\n[![build status][build-badge]][build]\n[![code coverage][coverage-badge]][coverage]\n[![npm version][version-badge]][package]\n\n[build-badge]: https://img.shields.io/github/actions/workflow/status/krakenjs/post-robot/main.yaml?branch=main\u0026logo=github\u0026style=flat-square\n[build]: https://github.com/krakenjs/post-robot/actions?query=workflow%3Abuild\n[coverage-badge]: https://img.shields.io/codecov/c/github/krakenjs/post-robot.svg?style=flat-square\n[coverage]: https://codecov.io/github/krakenjs/post-robot/\n[version-badge]: https://img.shields.io/npm/v/post-robot.svg?style=flat-square\n[package]: https://www.npmjs.com/package/post-robot\n\nCross domain post-messaging on the client side, using a simple listener/client pattern.\n\nSend a message to another window, and:\n\n- [Get a response](#simple-listener-and-sender-with-error-handling) from the window you messaged\n- [Pass functions](#functions) to another window, across different domains\n- [Handle any errors](#simple-listener-and-sender-with-error-handling) that prevented your message from getting through\n- Don't worry about serializing your messages; [just send javascript objects](#simple-listener-and-sender-with-error-handling)\n- Use [promises](#listener-with-promise-response) or [async/await](#async--await) to wait for responses from windows you message\n- Set up a [secure message channel](#secure-message-channel) between two windows on a certain domain\n- Send messages between a [parent and a popup window](#parent-to-popup-messaging) in IE\n\n## Serialization\n\npost-robot will serialize and deserialize the following data types in messages:\n\n- Objects, arrays, strings, numbers, booleans, null\n  - Note: this includes any JSON-serializable types\n- Functions\n  - Note: the function passed will be a [reference to the original function](#functions), and the deserialized function will always return a `Promise` - specifically a [`ZalgoPromise`](https://github.com/krakenjs/zalgo-promise)\n- Promises\n  - Note: deserialized promises will be instances of [`ZalgoPromise`](https://github.com/krakenjs/zalgo-promise)\n- Error objects\n  - e.g. `new Error(\"This error will self-destruct in 10, 9, 8...\")`\n- Regex objects\n  - e.g. `/[a-zA-Z0-9]*/`\n\n## Simple listener and sender\n\n```javascript\n// Set up a listener\n\npostRobot.on(\"getUser\", function (event) {\n  // Have it return some data to the calling window\n\n  return {\n    id: 1234,\n    name: \"Zippy the Pinhead\",\n\n    // Yep, we're even returning a function to the other window!\n\n    logout: function () {\n      return $currentUser.logout();\n    },\n  };\n});\n```\n\n```javascript\n// Call the listener, on a different window, on a different domain\n\npostRobot\n  .send(someWindow, \"getUser\", { id: 1337 })\n  .then(function (event) {\n    var user = event.data;\n\n    console.log(event.source, event.origin, \"Got user:\", user);\n\n    // Call the user.logout function from the other window!\n\n    user.logout();\n  })\n  .catch(function (err) {\n    // Handle any errors that stopped our call from going through\n\n    console.error(err);\n  });\n```\n\n## Listener with promise response\n\n```javascript\npostRobot.on(\"getUser\", function (event) {\n  return getUser(event.data.id).then(function (user) {\n    return {\n      name: user.name,\n    };\n  });\n});\n```\n\n## One-off listener\n\n```javascript\npostRobot.once(\"getUser\", function (event) {\n  return {\n    name: \"Noggin the Nog\",\n  };\n});\n```\n\n## Cancelling a listener\n\n```javascript\nvar listener = postRobot.on(\"getUser\", function (event) {\n  return {\n    id: event.data.id,\n    name: \"Zippy the Pinhead\",\n  };\n});\n\nlistener.cancel();\n```\n\n## Listen for messages from a specific window\n\n```javascript\npostRobot.on(\"getUser\", { window: window.parent }, function (event) {\n  return {\n    name: \"Guybrush Threepwood\",\n  };\n});\n```\n\n## Listen for messages from a specific domain\n\n```javascript\npostRobot.on(\"getUser\", { domain: \"http://zombo.com\" }, function (event) {\n  return {\n    name: \"Manny Calavera\",\n  };\n});\n```\n\n## Set a timeout for a response\n\n```javascript\npostRobot\n  .send(someWindow, \"getUser\", { id: 1337 }, { timeout: 5000 })\n  .then(function (event) {\n    console.log(event.source, event.origin, \"Got user:\", event.data.name);\n  })\n  .catch(function (err) {\n    console.error(err);\n  });\n```\n\n## Send a message to a specific domain\n\n```javascript\npostRobot\n  .send(someWindow, \"getUser\", { id: 1337 }, { domain: \"http://zombo.com\" })\n  .then(function (event) {\n    console.log(event.source, event.origin, \"Got user:\", event.data.name);\n  });\n```\n\n## Async / Await\n\n```javascript\npostRobot.on(\"getUser\", async ({ source, origin, data }) =\u003e {\n  let user = await getUser(data.id);\n\n  return {\n    id: data.id,\n    name: user.name,\n  };\n});\n```\n\n```javascript\ntry {\n  let { source, origin, data } = await postRobot.send(someWindow, `getUser`, {\n    id: 1337,\n  });\n  console.log(source, origin, \"Got user:\", data.name);\n} catch (err) {\n  console.error(err);\n}\n```\n\n## Secure Message Channel\n\nFor security reasons, it is recommended that you always explicitly specify the window and domain you want to listen\nto and send messages to. This creates a secure message channel that only works between two windows on the specified domain:\n\n```javascript\npostRobot.on(\n  \"getUser\",\n  { window: childWindow, domain: \"http://zombo.com\" },\n  function (event) {\n    return {\n      id: event.data.id,\n      name: \"Frodo\",\n    };\n  }\n);\n```\n\n```javascript\npostRobot\n  .send(someWindow, \"getUser\", { id: 1337 }, { domain: \"http://zombo.com\" })\n  .then(function (event) {\n    console.log(event.source, event.origin, \"Got user:\", event.data.name);\n  })\n  .catch(function (err) {\n    console.error(err);\n  });\n```\n\n## Functions\n\nPost robot lets you send across functions in your data payload, fairly seamlessly.\n\nFor example:\n\n```javascript\npostRobot.on(\"getUser\", function (event) {\n  return {\n    id: event.data.id,\n    name: \"Nogbad the Bad\",\n\n    logout: function () {\n      currentUser.logout();\n    },\n  };\n});\n```\n\n```javascript\npostRobot.send(myWindow, \"getUser\", { id: 1337 }).then(function (event) {\n  var user = event.data;\n\n  user.logout().then(function () {\n    console.log(\"User was logged out\");\n  });\n});\n```\n\nThe function `user.logout()` will be called on the **original** window. Post Robot transparently messages back to the\noriginal window, calls the function that was passed, then messages back with the result of the function.\n\nBecause this uses post-messaging behind the scenes and is therefore always async, `user.logout()` will **always** return a promise, and must be `.then`'d or `await`ed.\n\n## Parent to popup messaging\n\nUnfortunately, IE blocks direct post messaging between a parent window and a popup, on different domains.\n\nIn order to use post-robot in IE9+ with popup windows, you will need to set up an invisible 'bridge' iframe on your parent page:\n\n```\n   [ Parent page ]\n\n+---------------------+          [ Popup ]\n|        xx.com       |\n|                     |      +--------------+\n|  +---------------+  |      |    yy.com    |\n|  |    [iframe]   |  |      |              |\n|  |               |  |      |              |\n|  | yy.com/bridge |  |      |              |\n|  |               |  |      |              |\n|  |               |  |      |              |\n|  |               |  |      |              |\n|  |               |  |      +--------------+\n|  +---------------+  |\n|                     |\n+---------------------+\n```\n\na. Use the special `ie` build of post-robot: `dist/post-robot.ie.js`.\n\nb. Create a bridge path on the domain of your popup, for example `http://yy.com/bridge.html`, and include post-robot:\n\n```html\n\u003cscript src=\"http://yy.com/js/post-robot.ie.js\"\u003e\u003c/script\u003e\n```\n\nc. In the parent page on `xx.com` which opens the popup, include the following javascript:\n\n```html\n\u003cscript\u003e\n  postRobot.bridge.openBridge(\"http://yy.com/bridge.html\");\n\u003c/script\u003e\n```\n\nNow `xx.com` and `yy.com` can communicate freely using post-robot, in IE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrakenjs%2Fpost-robot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkrakenjs%2Fpost-robot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkrakenjs%2Fpost-robot/lists"}