Repository: sockjs/sockjs-client
Branch: main
Commit: dd3f1e48c9c6
Files: 104
Total size: 375.9 KB
Directory structure:
gitextract_hk8w3kor/
├── .eslintignore
├── .eslintrc
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── node.js.yml
│ └── stale.yml
├── .gitignore
├── .jscsrc
├── .npmignore
├── .nvmrc
├── AUTHORS
├── CODE_OF_CONDUCT.md
├── Changelog.md
├── LICENSE
├── README.md
├── build.sh
├── dist/
│ ├── sockjs-esm.js
│ └── sockjs.d.ts
├── gulpfile.js
├── karma.conf.js
├── lib/
│ ├── entry.js
│ ├── event/
│ │ ├── close.js
│ │ ├── emitter.js
│ │ ├── event.js
│ │ ├── eventtarget.js
│ │ └── trans-message.js
│ ├── facade.js
│ ├── iframe-bootstrap.js
│ ├── info-ajax.js
│ ├── info-iframe-receiver.js
│ ├── info-iframe.js
│ ├── info-receiver.js
│ ├── location.js
│ ├── main.js
│ ├── shims.js
│ ├── transport/
│ │ ├── browser/
│ │ │ ├── abstract-xhr.js
│ │ │ ├── eventsource.js
│ │ │ └── websocket.js
│ │ ├── driver/
│ │ │ ├── eventsource.js
│ │ │ ├── websocket.js
│ │ │ └── xhr.js
│ │ ├── eventsource.js
│ │ ├── htmlfile.js
│ │ ├── iframe.js
│ │ ├── jsonp-polling.js
│ │ ├── lib/
│ │ │ ├── ajax-based.js
│ │ │ ├── buffered-sender.js
│ │ │ ├── iframe-wrap.js
│ │ │ ├── polling.js
│ │ │ └── sender-receiver.js
│ │ ├── receiver/
│ │ │ ├── eventsource.js
│ │ │ ├── htmlfile.js
│ │ │ ├── jsonp.js
│ │ │ └── xhr.js
│ │ ├── sender/
│ │ │ ├── jsonp.js
│ │ │ ├── xdr.js
│ │ │ ├── xhr-cors.js
│ │ │ ├── xhr-fake.js
│ │ │ └── xhr-local.js
│ │ ├── websocket.js
│ │ ├── xdr-polling.js
│ │ ├── xdr-streaming.js
│ │ ├── xhr-polling.js
│ │ └── xhr-streaming.js
│ ├── transport-list.js
│ ├── utils/
│ │ ├── browser-crypto.js
│ │ ├── browser.js
│ │ ├── escape.js
│ │ ├── event.js
│ │ ├── iframe.js
│ │ ├── log.js
│ │ ├── object.js
│ │ ├── random.js
│ │ ├── transport.js
│ │ └── url.js
│ └── version.js
├── package.json
└── tests/
├── .eslintrc
├── browser.js
├── browser_targets.js
├── html/
│ ├── example-cursors.html
│ ├── iframe.html
│ ├── index.html
│ ├── lib/
│ │ └── worker.js
│ ├── smoke-latency.html
│ ├── smoke-reconnect.html
│ ├── sockjs-in-parent.html
│ └── web-worker.html
├── lib/
│ ├── batch-tests.js
│ ├── echo-tests.js
│ ├── end-to-end.js
│ ├── iframe.js
│ ├── main-node.js
│ ├── main.js
│ ├── receivers.js
│ ├── senders.js
│ ├── test-utils.js
│ ├── transports.js
│ ├── utils-event.js
│ └── utils.js
├── node.js
└── support/
├── domain.js
├── manual.js
├── sockjs_app.js
└── sockjs_server.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintignore
================================================
dist/*
build/*
tests/html/lib/sockjs.js
tests/html/static/*
================================================
FILE: .eslintrc
================================================
{
"extends": ["eslint:recommended"],
"env": {
"node": true,
"browser": true
},
"rules": {
"consistent-this": ["error", "self"],
"quotes": ["warn", "single", "avoid-escape"],
"no-space-before-semi": "off",
"no-underscore-dangle": "off",
"no-mixed-requires": "off"
},
"globals": {
"Uint8Array": true
}
}
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
tidelift: npm/sockjs-client
================================================
FILE: .github/workflows/node.js.yml
================================================
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
name: Node.js CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
================================================
FILE: .github/workflows/stale.yml
================================================
name: Mark stale issues
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
days-before-close: 5
stale-issue-message: 'This issue has been inactive for 30 days. It will be in closed in 5 days without any new activity.'
stale-issue-label: 'no-issue-activity'
any-of-labels: 'inactive'
================================================
FILE: .gitignore
================================================
.idea
.pidfile.pid
node_modules
npm-debug.log
sockjs.js
sockjs.min.js
build/
tests/html/lib/sockjs.js.map
local.log
================================================
FILE: .jscsrc
================================================
{
"requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"],
"requireSpaceAfterKeywords": ["do", "for", "if", "else", "switch", "case", "try", "catch", "void", "while", "with", "return", "typeof"],
"requireSpaceBeforeBlockStatements": true,
"requireParenthesesAroundIIFE": true,
"requireSpacesInConditionalExpression": true,
"requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInFunction": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInCallExpression": true,
"requireBlocksOnNewline": true,
"disallowCommaBeforeLineBreak": true,
"requireCapitalizedConstructors": true,
"validateQuoteMarks": { "escape": true, "mark": "'" },
"validateIndentation": 2,
"validateParameterSeparator": ", "
}
================================================
FILE: .npmignore
================================================
tests/
dist/
!dist/sockjs.js
!dist/sockjs.js.map
!dist/sockjs.min.js
!dist/sockjs.min.js.map
build/
.eslintrc
.eslintignore
.jscsrc
.nvmrc
bower.json
gulpfile.js
Makefile
img/
karma.conf.js
build.sh
.github/
local.log
================================================
FILE: .nvmrc
================================================
12
================================================
FILE: AUTHORS
================================================
# This is the list of sockjs-client authors for copyright purposes.
#
# This does not necessarily list everyone who has contributed code, since in
# some cases, their employer may be the copyright holder. To see the full list
# of contributors, see the revision history in source control.
Bryce Kahle
Marek Majkowski
VMWare
LearnBoost
Julian Aubourg
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at sockjs@brycekahle.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: Changelog.md
================================================
1.6.2
==
* Added ECMAScript build with TypeScript types.
1.6.1
==
Fixes
* Update `eventsource` to `2.0.2` due to CVE-2022-1650. Fixes #590
* Update `minimist` to `1.2.6`. Fixes #585
1.6.0
==
Fixes
* Remove `agent: false` to allow usage of `globalAgent`. Fixes #421
dependencies
* Update `url-parse` due to CVE-2022-0686, CVE-2022-0639, and CVE-2022-0512. Fixes #576
* Remove `json3` dependency. Fixes #476
* Update `eventsource` to `1.1.0`
* Update `faye-websocket` to `0.11.4`
* Update `debug` to `3.2.7`
devDependencies
* Update `follow-redirects` (devDep) due to CVE-2022-0536 and CVE-2022-0155
* Update `karma` (devDep) due to CVE-2022-0437
* Update `cached-path-relative` (devDep) due to CVE-2021-23518
* Update `fsevents` (devDep) to fix:
* `ini` CVE-2020-7788
* `minimist` CVE-2020-7598
* `tar` CVE-2021-37713, CVE-2021-37701, CVE-2021-32804, CVE-2021-32803
* Update `copy-props` (devDep) due to CVE-2020-28503
* Update `eslint`, `mocha`, `gulp-replace`, `karma-browserify`, `gulp-sourcemaps`, and `browserify`
Other Changes
* Remove bower
* Remove Travis CI
* Require Node.js 12
1.5.2
==
* Update `url-parse` due to CVE-2021-3664.
1.5.1
==
* Update `url-parse` due to CVE-2021-27515.
1.5.0
==
* Update `url-parse`, `kind-of`, `minimist`, `websocket-extensions` due to security vulnerabilies.
* Update dev dependencies.
* Allow loopback address hostnames on a secure page. Fixes #486
* Enable eventsource transport for node.js clients.
1.4.0
==
* Add `timeout` option to set a minimum transport timeout. Fixes #403
* Update dev deps to fix security warnings from `npm audit`
* Guard against null `this._transport` in `debug` statement. Fixes #448
1.3.0
==
* Revert `debug` to `^3` because v4 starts using ES6. Fixes #457
1.2.0
==
* Update all outdated dependencies
* Switch to karma and browserstack for running automated browser tests
1.1.5
==
* Wrap the the contentWindow access in a try/catch block when in setTimeout #363
* Revised example in README #356
* Fix connection close when Transport timeout #358
* Fixed crash with react-native@0.45.1 on Android #386
* Update jsDelivr link #404, #405
* Remove Sauce Labs unsupported browsers
* Add link to rust server implementation #411
* location.protocol should include final `:` #396
1.1.4
==
* Upgrade `debug` and fix object key literal mangling, fixes regression in Opera 11.10 #359
* Trim descriptions in package.json and bower.json - #372
1.1.3
==
* Bad publish to NPM (removed)
1.1.2
==
* Ensure both sender and receiver are cleaned upon close - #342
* Remove event listeners before calling `close` - #344
* Update documentation links - #351, #339, #316
* Explicitly export `undefined` when `WebSocket` does not exist. Fixes Webpack. #321
* Include `dist` folder on npm - #265
* Simplify build setup
* Update to Node.js 6.9
* Add sourcemap for minified version
* Remove unused String.trim shim
1.1.1
==
* Do not pass `protocols` or `options` arguments to browser WebSocket constructor - #309
1.1.0
==
* Fix IE7/8 usage of `console.log` which does not have `apply` - #279
* Remove `dbg` global variable - #282
* Bump `faye-websocket` version to `0.11.0` - #267
* Optimize `arguments` usage - #263
* Add sourcemap file to dist folder - #237
* Add way to transparently pass transport-specific options - #272
1.0.3
==
* Use `https` module for xhr requests in node when url uses https - #254
1.0.2
==
* Fix iframe info receiver url
* Move iframe.contentWindow check inside setTimeout - #246
1.0.1
==
* Use proper base url for iframe-based info receiver - #249
* Don't register unload event in chrome packaged app - #223
* Allow custom session ids - #250
* Remove version property from bower.json - #247
* Update example CDN url - #244
1.0.0
===
* Simplify url handling by delegating to `url-parse` - #242
* Upgrade to `url-parse` 1.0.1 to fix colon issue if auth has no password
1.0.0-beta.13
===
* Transport timeout on connection should fallback - #238
1.0.0-beta.12
====
* Upgrade `url-parse` to 1.0.0 to fix #218 again
1.0.0-beta.10
====
* Upgrade `url-parse` to 0.2.3 to fix #222
1.0.0-beta.9
====
* Upgrade `url-parse` to 0.2.1 to fix 'too much recursion' errors
1.0.0-beta.8
====
* Upgrade `url-parse` to 0.2.0 to fix inheritance issues
1.0.0-beta.7
====
* Upgrade `url-parse` to 0.1.5 to fix #218
* Don't strip basic auth from url - #219
1.0.0-beta.6
====
* Upgrade `url-parse` to 0.1.3 to avoid CSP issues
1.0.0-beta.5
=====
* Upgrade `url-parse` to 0.1.1 to fix #214
1.0.0-beta.4
=====
* Upgrade `url-parse` to 0.1.0 and `sockjs` to 0.3.11
* Update .npmignore
1.0.0-beta.3
=====
* Move `debug` from devDependencies to dependencies
1.0.0-beta.2
=====
* Relax requirements when using same origin XHR - #80
* Upgrade to JSON3 from JSON2 - #123
* Package library with browserify supporting the UMD pattern - #184
* Move tests to JavaScript
* Add Gulp.js build script
* Fix getOrigin for file:/// urls and standard ports - #173
* Add onerror event handlers to Websockets - #169
* Increase RTO lower bound to prevent spurious timeouts on IE8/9 - #161
* Use window.crypto for random values when available - #128
* Fix handling of listeners added and removed mid-dispatch - #127
* Fix XHR Streaming for IE8 - #83
* Remove explicit AMD name - #107
* Check for an empty response from /info request - #143
* Add Content-Type to XHR requests to fix issue over HTTPS on Galaxy S4 - #164
* Fix iframe fallback when message is sent from a popup in IE7/8 - #166
* Add support for query strings on the url - #72
* Now works inside of Web Workers - #181
* Support EventSource / Server Sent Events outside of iframes - #201
* Rename protocols to transports - #65
* Allow transports which need the body to trigger on 'interactive' readyState - #175
* try/catch access to document.domain - #187
* Use `window.location` instead of `document.location` - #195
* Allow usage from node.js with same API
0.3.4
=====
* Mentioned njoyce's fork of sockjs-gevent.
* #90 - Don't catch onbeforeunload event - it breaks javascript://
links in IE.
* IE mangles 204 response code for 1223 on ajax, see:
http://bugs.jquery.com/ticket/1450
* Make `new` optional for SockJS constructor (via substack).
* It is impossible to cancel JSONP polling request - compensate for that.
* Refactored EventEmitter prototype (used only internally)
* #66 - Failure to post data to /xhr_send should kill the session
0.3.2
=====
* #77 - Getting /info on modern browsers when html is served from
file:// urls was broken.
0.3.1
=====
* #61 - Meteor guys found that we unintentionally catch "onopen" errors.
* #63 - Meteorjs guys found that xhr-streaming on Safari sometimes
left busy cursor running.
* Increased allowed time for websocket transport (from 1 rtt to 2),
this should make ws transport more reliable over SSL, at the cost
of slightly longer connection time for users with blocked ws.
* #57 - previous fix didn't really work, sockjs-client still left
a mess in browsers history when using iframe transports. This
is fixed now.
* #60 - Opera 12 (next) claims to do AJAX2 / CORS, but can't
do xhr-streaming.
* #58 - onunload test sometimes failed on Safari on windows
* Updated readme WRT websocket protocols
* Updated readme WRT deployments on heroku
* Add minimalistic license block to every source file.
0.3.0
=====
* Temporarily disabled iframe tests - they are failing unpredictably.
* #57 - pointing an iframe to "about:blank" during cleanup caused
Opera to messup history.
* #55 - Improved iframe abstraction (reduced a possible mem leak)
* Refactored AJAX abstractions, for better CORS handing - again.
* Add additional parent origin security check to an iframe.
* Urls with hashes or query strings can't be passed to SockJS.
* #18 - Mention workaround for Firefox ESC key issue
* #53 - AMD compliance
* sockjs/sockjs-protocol#28 - always use square brackets for
websocket frames
* #51 - initial support for IE10 - try XHR before XDR
* #28 - handle onunload / onbeforeunload in a more robust fashion
* #49 - support SockJS-client being used from files served from
file:// urls.
0.2.1
=====
* "smoke-latency.html" test was unnecesairly sending too much data.
* Bumped core dependencies (coffee-script and uglify-js)
* Minor updates to the README, few cosmetic changes in the code.
0.2.0
=====
* The API had changed - use `protocols_whitelist` option instead of
passing an array of protocols as a second argument to SockJS constructor.
* Dropped 'chunking-test' functionality and replace it with 'info'.
* Rewritten protocol-choosing alogirthm, see "utils.detectProtocols" method.
* Use dynamic protocol timeouts based on RTT, not hardcoded 5 seconds
* #34 - Don't ever reuse `session_id`, especially when trying
fallback protocols.
* The test server got moved from SockJS-client to SockJS-node.
* Don't test unicode surrogates - it can't work in some environments.
* XHR/XDR helpers were rewritten, ajax transports were simplified.
* Added a domain check in the iframe to improve security.
* SockJS will now trigger 1002 error if there is a problem during handshake
instead of 2000 error.
* Smoke-throughput test is renamed to smoke-latency.
0.1.2
=====
* #29 - Allow all unicode characters to be send over SockJS.
* #15 - SockJS should now work fine even if the connection is started
in HEAD, before BODY is loaded.
* #28 - In rare circumstances WebSocket connection can be left intact
after the page is unloaded in FireFox.
* Updated scripts to work with Node 0.6.
* Initial work to do better QUnit testing.
* Updated the minifying script (always escape unicode chars, remove
trailing comment).
* Use string instead of array of chars (utils.js:random_number_string).
0.1.1
=====
* #21 Get JsonP transport working on IE9 (Vladimir Dronnikov).
* #26 Emit heartbeat event.
* #27 Include license inline.
0.1.0
=====
* SockJS-client can only send UTF-8 encodable strings. Previously we
took advantage of rich data structures and automatically
json-encoded them, but this got removed. Now, all data passed to
`send` will be converted to string. This is also how native
* `status` property on `EventClose` is renamed to `code`
as per Websocket API
WebSockets behave.
* The test server was updated to new `sockjs-node` API
* Fixed problem with Jsonp-polling transport on IE9
* Repository was moved - updated links.
0.0.4
=====
* All transports were refactored, some transports were introduced:
htmlfile and separate xhr-streaming.
* Added logic to detect support for http chunking, and thus a
possibility to rule out streaming transports before running them.
* Added 'cookie' option, useful for cookie-based load balancing
(currently, it make a difference only for IE).
* Added hack to prevent EventSource from crashing Safari and Chrome.
* Loads and loads of other small and medium changes.
0.0.2
=====
* Initial support for JSESSIONID based load balancing. Currently
doesn't play nicely with IE XDomainRequest transport.
0.0.1
=====
* Initial release.
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2011-2018 The sockjs-client Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# SockJS-client
[](https://www.npmjs.com/package/sockjs-client)[](https://libraries.io/npm/sockjs-client)[](https://gitter.im/sockjs/sockjs-client)[](CODE_OF_CONDUCT.md)
[](https://automate.browserstack.com/public-build/N3V0cStKM3RtUy9Bb2l2cHFhMVdobTZnUitBZ1lLcUkwYnl2TWgyMHppQT0tLWxncU5UeTdLb0Rqc1VQQTI5SklRelE9PQ==--596ccf9d3cd2f462f1043ee6803a9405e00446ac)
# SockJS for enterprise
Available as part of the Tidelift Subscription.
The maintainers of SockJS and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-sockjs-client?utm_source=npm-sockjs-client&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
# Summary
SockJS is a browser JavaScript library that provides a WebSocket-like
object. SockJS gives you a coherent, cross-browser, Javascript API
which creates a low latency, full duplex, cross-domain communication
channel between the browser and the web server.
Under the hood SockJS tries to use native WebSockets first. If that
fails it can use a variety of browser-specific transport protocols and
presents them through WebSocket-like abstractions.
SockJS is intended to work for all modern browsers and in environments
which don't support the WebSocket protocol -- for example, behind restrictive
corporate proxies.
SockJS-client does require a server counterpart:
* [SockJS-node](https://github.com/sockjs/sockjs-node) is a SockJS
server for Node.js.
Philosophy:
* The API should follow
[HTML5 Websockets API](https://www.w3.org/TR/websockets/) as
closely as possible.
* All the transports must support cross domain connections out of the
box. It's possible and recommended to host a SockJS server on a
different server than your main web site.
* There is support for at least one streaming protocol for every
major browser.
* Streaming transports should work cross-domain and
should support cookies (for cookie-based sticky sessions).
* Polling transports are used as a fallback for old browsers and
hosts behind restrictive proxies.
* Connection establishment should be fast and lightweight.
* No Flash inside (no need to open port 843 - which doesn't work
through proxies, no need to host 'crossdomain.xml', no need
[to wait for 3 seconds](https://github.com/gimite/web-socket-js/issues/49)
in order to detect problems)
Subscribe to
[SockJS mailing list](https://groups.google.com/forum/#!forum/sockjs) for
discussions and support.
# SockJS family
* [SockJS-client](https://github.com/sockjs/sockjs-client) JavaScript client library
* [SockJS-node](https://github.com/sockjs/sockjs-node) Node.js server
* [SockJS-erlang](https://github.com/sockjs/sockjs-erlang) Erlang server
* [SockJS-cyclone](https://github.com/flaviogrossi/sockjs-cyclone) Python/Cyclone/Twisted server
* [SockJS-tornado](https://github.com/MrJoes/sockjs-tornado) Python/Tornado server
* [SockJS-twisted](https://github.com/DesertBus/sockjs-twisted/) Python/Twisted server
* [SockJS-aiohttp](https://github.com/aio-libs/sockjs/) Python/Aiohttp server
* [Spring Framework](https://projects.spring.io/spring-framework) Java [client](https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.html#websocket-fallback-sockjs-client) & server
* [vert.x](https://github.com/vert-x/vert.x) Java/vert.x server
* [Xitrum](https://xitrum-framework.github.io/) Scala server
* [Atmosphere Framework](https://github.com/Atmosphere/atmosphere) JavaEE Server, Play Framework, Netty, Vert.x
* [Actix SockJS](https://github.com/fafhrd91/actix-sockjs) Rust Server, Actix Framework
Work in progress:
* [SockJS-ruby](https://github.com/nyarly/sockjs-ruby)
* [SockJS-netty](https://github.com/cgbystrom/sockjs-netty)
* [SockJS-gevent](https://github.com/ksava/sockjs-gevent) ([SockJS-gevent fork](https://github.com/njoyce/sockjs-gevent))
* [pyramid-SockJS](https://github.com/fafhrd91/pyramid_sockjs)
* [wildcloud-websockets](https://github.com/wildcloud/wildcloud-websockets)
* [wai-SockJS](https://github.com/Palmik/wai-sockjs)
* [SockJS-perl](https://github.com/vti/sockjs-perl)
* [SockJS-go](https://github.com/igm/sockjs-go/)
* [syp.biz.SockJS.NET](https://github.com/sypbiz/SockJS.NET) - .NET port of the SockJS client
# Getting Started
SockJS mimics the [WebSockets API](https://www.w3.org/TR/websockets/),
but instead of `WebSocket` there is a `SockJS` Javascript object.
First, you need to load the SockJS JavaScript library. For example, you can
put that in your HTML head:
```html
```
After the script is loaded you can establish a connection with the
SockJS server. Here's a simple example:
```javascript
var sock = new SockJS('https://mydomain.com/my_prefix');
sock.onopen = function() {
console.log('open');
sock.send('test');
};
sock.onmessage = function(e) {
console.log('message', e.data);
sock.close();
};
sock.onclose = function() {
console.log('close');
};
```
# SockJS-client API
## SockJS class
Similar to the 'WebSocket' API, the 'SockJS' constructor takes one or more arguments:
```javascript
var sockjs = new SockJS(url, _reserved, options);
```
`url` may contain a query string, if one is desired.
Where `options` is a hash which can contain:
* **server (string)**
String to append to url for actual data connection. Defaults to a random 4 digit number.
* **transports (string OR array of strings)**
Sometimes it is useful to disable some fallback transports. This
option allows you to supply a list transports that may be used by
SockJS. By default all available transports will be used.
* **sessionId (number OR function)**
Both client and server use session identifiers to distinguish connections.
If you specify this option as a number, SockJS will use its random string
generator function to generate session ids that are N-character long
(where N corresponds to the number specified by **sessionId**).
When you specify this option as a function, the function must return a
randomly generated string. Every time SockJS needs to generate a session
id it will call this function and use the returned string directly.
If you don't specify this option, the default is to use the default random
string generator to generate 8-character long session ids.
* **timeout (number)**
Specify a minimum timeout in milliseconds to use for the transport connections.
By default this is dynamically calculated based on the measured RTT and
the number of expected round trips. This setting will establish a minimum,
but if the calculated timeout is higher, that will be used.
Although the 'SockJS' object tries to emulate the 'WebSocket'
behaviour, it's impossible to support all of its features. An
important SockJS limitation is the fact that you're not allowed to
open more than one SockJS connection to a single domain at a time.
This limitation is caused by an in-browser limit of outgoing
connections - usually [browsers don't allow opening more than two
outgoing connections to a single domain](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser). A single SockJS session
requires those two connections - one for downloading data, the other for
sending messages. Opening a second SockJS session at the same time
would most likely block, and can result in both sessions timing out.
Opening more than one SockJS connection at a time is generally a
bad practice. If you absolutely must do it, you can use
multiple subdomains, using a different subdomain for every
SockJS connection.
# Supported transports, by browser (html served from http:// or https://)
_Browser_ | _Websockets_ | _Streaming_ | _Polling_
----------------|------------------|-------------|-------------------
IE 6, 7 | no | no | jsonp-polling
IE 8, 9 (cookies=no) | no | xdr-streaming † | xdr-polling †
IE 8, 9 (cookies=yes)| no | iframe-htmlfile | iframe-xhr-polling
IE 10 | rfc6455 | xhr-streaming | xhr-polling
Chrome 6-13 | hixie-76 | xhr-streaming | xhr-polling
Chrome 14+ | hybi-10 / rfc6455| xhr-streaming | xhr-polling
Firefox <10 | no ‡ | xhr-streaming | xhr-polling
Firefox 10+ | hybi-10 / rfc6455| xhr-streaming | xhr-polling
Safari 5.x | hixie-76 | xhr-streaming | xhr-polling
Safari 6+ | rfc6455 | xhr-streaming | xhr-polling
Opera 10.70+ | no ‡ | iframe-eventsource | iframe-xhr-polling
Opera 12.10+ | rfc6455 | xhr-streaming | xhr-polling
Konqueror | no | no | jsonp-polling
* **†**: IE 8+ supports [XDomainRequest][^9], which is
essentially a modified AJAX/XHR that can do requests across
domains. But unfortunately it doesn't send any cookies, which
makes it inappropriate for deployments when the load balancer uses
JSESSIONID cookie to do sticky sessions.
* **‡**: Firefox 4.0 and Opera 11.00 and shipped with disabled
Websockets "hixie-76". They can still be enabled by manually
changing a browser setting.
# Supported transports, by browser (html served from file://)
Sometimes you may want to serve your html from "file://" address - for
development or if you're using PhoneGap or similar technologies. But
due to the Cross Origin Policy files served from "file://" have no
Origin, and that means some of SockJS transports won't work. For this
reason the SockJS transport table is different than usually, major
differences are:
_Browser_ | _Websockets_ | _Streaming_ | _Polling_
----------------|---------------|--------------------|-------------------
IE 8, 9 | same as above | iframe-htmlfile | iframe-xhr-polling
Other | same as above | iframe-eventsource | iframe-xhr-polling
# Supported transports, by name
_Transport_ | _References_
---------------------|---------------
websocket (rfc6455) | [rfc 6455][^10]
websocket (hixie-76) | [draft-hixie-thewebsocketprotocol-76][^1]
websocket (hybi-10) | [draft-ietf-hybi-thewebsocketprotocol-10][^2]
xhr-streaming | Transport using [Cross domain XHR][^5] [streaming][^7] capability (readyState=3).
xdr-streaming | Transport using [XDomainRequest][^9] [streaming][^7] capability (readyState=3).
eventsource | [EventSource/Server-sent events][^4].
iframe-eventsource | [EventSource/Server-sent events][^4] used from an [iframe via postMessage][^3].
htmlfile | [HtmlFile][^8].
iframe-htmlfile | [HtmlFile][^8] used from an [iframe via postMessage][^3].
xhr-polling | Long-polling using [cross domain XHR][^5].
xdr-polling | Long-polling using [XDomainRequest][^9].
iframe-xhr-polling | Long-polling using normal AJAX from an [iframe via postMessage][^3].
jsonp-polling | Slow and old fashioned [JSONP polling][^6]. This transport will show "busy indicator" (aka: "spinning wheel") when sending data.
[^1]: https://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
[^2]: https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
[^3]: https://developer.mozilla.org/en/DOM/window.postMessage
[^4]: https://html.spec.whatwg.org/multipage/comms.html#server-sent-events
[^5]: https://secure.wikimedia.org/wikipedia/en/wiki/XMLHttpRequest#Cross-domain_requests
[^6]: https://secure.wikimedia.org/wikipedia/en/wiki/JSONP
[^7]: http://www.debugtheweb.com/test/teststreaming.aspx
[^8]: http://cometdaily.com/2007/11/18/ie-activexhtmlfile-transport-part-ii/
[^9]: https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/
[^10]: https://www.rfc-editor.org/rfc/rfc6455.txt
# Connecting to SockJS without the client
Although the main point of SockJS is to enable browser-to-server
connectivity, it is possible to connect to SockJS from an external
application. Any SockJS server complying with 0.3 protocol does
support a raw WebSocket url. The raw WebSocket url for the test server
looks like:
* ws://localhost:8081/echo/websocket
You can connect any WebSocket RFC 6455 compliant WebSocket client to
this url. This can be a command line client, external application,
third party code or even a browser (though I don't know why you would
want to do so).
# Deployment
You should use a version of sockjs-client
that supports the protocol used by your server. For example:
```html
```
For server-side deployment tricks, especially about load balancing and
session stickiness, take a look at the
[SockJS-node readme](https://github.com/sockjs/sockjs-node#readme).
# Development and testing
SockJS-client needs [node.js](https://nodejs.org/) for running a test
server and JavaScript minification. If you want to work on
SockJS-client source code, checkout the git repo and follow these
steps:
cd sockjs-client
npm install
To generate JavaScript, run:
gulp browserify
To generate minified JavaScript, run:
gulp browserify:min
Both commands output into the `build` directory.
## Testing
Automated testing provided by:
Once you've compiled the SockJS-client you may want to check if your changes
pass all the tests.
npm run test:browser_local
This will start [karma](https://karma-runner.github.io) and a test support server.
# Browser Quirks
There are various browser quirks which we don't intend to address:
* Pressing ESC in Firefox, before Firefox 20, closes the SockJS connection. For a workaround
and discussion see [#18](https://github.com/sockjs/sockjs-client/issues/18).
* `jsonp-polling` transport will show a "spinning wheel" (aka. "busy indicator")
when sending data.
* You can't open more than one SockJS connection to one domain at the
same time due to [the browser's limit of concurrent connections](https://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser)
(this limit is not counting native WebSocket connections).
* Although SockJS is trying to escape any strange Unicode characters
(even invalid ones - [like surrogates \xD800-\xDBFF](https://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates) or [\xFFFE and \xFFFF](https://en.wikipedia.org/wiki/Unicode#Character_General_Category))
it's advisable to use only valid characters. Using invalid
characters is a bit slower, and may not work with SockJS servers
that have proper Unicode support.
* Having a global function called `onmessage` or such is probably a
bad idea, as it could be called by the built-in `postMessage` API.
* From SockJS' point of view there is nothing special about
SSL/HTTPS. Connecting between unencrypted and encrypted sites
should work just fine.
* Although SockJS does its best to support both prefix and cookie based
sticky sessions, the latter may not work well cross-domain with
browsers that don't accept third-party cookies by default (Safari).
In order to get around this make sure you're connecting to SockJS
from the same parent domain as the main site. For example
'sockjs.a.com' is able to set cookies if you're connecting from
'www.a.com' or 'a.com'.
* Trying to connect from secure "https://" to insecure "http://" is
not a good idea. The other way around should be fine.
* Long polling is known to cause problems on Heroku, but a
[workaround for SockJS is available](https://github.com/sockjs/sockjs-node/issues/57#issuecomment-5242187).
* SockJS [websocket transport is more stable over SSL](https://github.com/sockjs/sockjs-client/issues/94). If
you're a serious SockJS user then consider using SSL
([more info](https://www.ietf.org/mail-archive/web/hybi/current/msg01605.html)).
================================================
FILE: build.sh
================================================
#!/bin/bash
set -e
if [ "x${BROWSER}" = "x" ]; then
npm run lint
npm test
else
exit 1
fi
================================================
FILE: dist/sockjs-esm.js
================================================
var __getOwnPropNames = Object.getOwnPropertyNames;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// dist/sockjs.js
var require_sockjs = __commonJS({
"dist/sockjs.js"(exports, module) {
(function(f) {
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f();
} else if (typeof define === "function" && define.amd) {
define([], f);
} else {
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}
g.SockJS = f();
}
})(function() {
var define2, module2, exports2;
return function() {
function r(e, n, t) {
function o(i2, f) {
if (!n[i2]) {
if (!e[i2]) {
var c = "function" == typeof __require && __require;
if (!f && c)
return c(i2, true);
if (u)
return u(i2, true);
var a = new Error("Cannot find module '" + i2 + "'");
throw a.code = "MODULE_NOT_FOUND", a;
}
var p = n[i2] = { exports: {} };
e[i2][0].call(p.exports, function(r2) {
var n2 = e[i2][1][r2];
return o(n2 || r2);
}, p, p.exports, r, e, n, t);
}
return n[i2].exports;
}
for (var u = "function" == typeof __require && __require, i = 0; i < t.length; i++)
o(t[i]);
return o;
}
return r;
}()({ 1: [function(require2, module3, exports3) {
(function(global2) {
(function() {
"use strict";
var transportList = require2("./transport-list");
module3.exports = require2("./main")(transportList);
if ("_sockjs_onload" in global2) {
setTimeout(global2._sockjs_onload, 1);
}
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "./main": 14, "./transport-list": 16 }], 2: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), Event = require2("./event");
function CloseEvent() {
Event.call(this);
this.initEvent("close", false, false);
this.wasClean = false;
this.code = 0;
this.reason = "";
}
inherits(CloseEvent, Event);
module3.exports = CloseEvent;
}, { "./event": 4, "inherits": 57 }], 3: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), EventTarget = require2("./eventtarget");
function EventEmitter() {
EventTarget.call(this);
}
inherits(EventEmitter, EventTarget);
EventEmitter.prototype.removeAllListeners = function(type) {
if (type) {
delete this._listeners[type];
} else {
this._listeners = {};
}
};
EventEmitter.prototype.once = function(type, listener) {
var self2 = this, fired = false;
function g() {
self2.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
this.on(type, g);
};
EventEmitter.prototype.emit = function() {
var type = arguments[0];
var listeners = this._listeners[type];
if (!listeners) {
return;
}
var l = arguments.length;
var args = new Array(l - 1);
for (var ai = 1; ai < l; ai++) {
args[ai - 1] = arguments[ai];
}
for (var i = 0; i < listeners.length; i++) {
listeners[i].apply(this, args);
}
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener = EventTarget.prototype.addEventListener;
EventEmitter.prototype.removeListener = EventTarget.prototype.removeEventListener;
module3.exports.EventEmitter = EventEmitter;
}, { "./eventtarget": 5, "inherits": 57 }], 4: [function(require2, module3, exports3) {
"use strict";
function Event(eventType) {
this.type = eventType;
}
Event.prototype.initEvent = function(eventType, canBubble, cancelable) {
this.type = eventType;
this.bubbles = canBubble;
this.cancelable = cancelable;
this.timeStamp = +/* @__PURE__ */ new Date();
return this;
};
Event.prototype.stopPropagation = function() {
};
Event.prototype.preventDefault = function() {
};
Event.CAPTURING_PHASE = 1;
Event.AT_TARGET = 2;
Event.BUBBLING_PHASE = 3;
module3.exports = Event;
}, {}], 5: [function(require2, module3, exports3) {
"use strict";
function EventTarget() {
this._listeners = {};
}
EventTarget.prototype.addEventListener = function(eventType, listener) {
if (!(eventType in this._listeners)) {
this._listeners[eventType] = [];
}
var arr = this._listeners[eventType];
if (arr.indexOf(listener) === -1) {
arr = arr.concat([listener]);
}
this._listeners[eventType] = arr;
};
EventTarget.prototype.removeEventListener = function(eventType, listener) {
var arr = this._listeners[eventType];
if (!arr) {
return;
}
var idx = arr.indexOf(listener);
if (idx !== -1) {
if (arr.length > 1) {
this._listeners[eventType] = arr.slice(0, idx).concat(arr.slice(idx + 1));
} else {
delete this._listeners[eventType];
}
return;
}
};
EventTarget.prototype.dispatchEvent = function() {
var event = arguments[0];
var t = event.type;
var args = arguments.length === 1 ? [event] : Array.apply(null, arguments);
if (this["on" + t]) {
this["on" + t].apply(this, args);
}
if (t in this._listeners) {
var listeners = this._listeners[t];
for (var i = 0; i < listeners.length; i++) {
listeners[i].apply(this, args);
}
}
};
module3.exports = EventTarget;
}, {}], 6: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), Event = require2("./event");
function TransportMessageEvent(data) {
Event.call(this);
this.initEvent("message", false, false);
this.data = data;
}
inherits(TransportMessageEvent, Event);
module3.exports = TransportMessageEvent;
}, { "./event": 4, "inherits": 57 }], 7: [function(require2, module3, exports3) {
"use strict";
var iframeUtils = require2("./utils/iframe");
function FacadeJS(transport) {
this._transport = transport;
transport.on("message", this._transportMessage.bind(this));
transport.on("close", this._transportClose.bind(this));
}
FacadeJS.prototype._transportClose = function(code, reason) {
iframeUtils.postMessage("c", JSON.stringify([code, reason]));
};
FacadeJS.prototype._transportMessage = function(frame) {
iframeUtils.postMessage("t", frame);
};
FacadeJS.prototype._send = function(data) {
this._transport.send(data);
};
FacadeJS.prototype._close = function() {
this._transport.close();
this._transport.removeAllListeners();
};
module3.exports = FacadeJS;
}, { "./utils/iframe": 47 }], 8: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var urlUtils = require2("./utils/url"), eventUtils = require2("./utils/event"), FacadeJS = require2("./facade"), InfoIframeReceiver = require2("./info-iframe-receiver"), iframeUtils = require2("./utils/iframe"), loc = require2("./location");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:iframe-bootstrap");
}
module3.exports = function(SockJS, availableTransports) {
var transportMap = {};
availableTransports.forEach(function(at) {
if (at.facadeTransport) {
transportMap[at.facadeTransport.transportName] = at.facadeTransport;
}
});
transportMap[InfoIframeReceiver.transportName] = InfoIframeReceiver;
var parentOrigin;
SockJS.bootstrap_iframe = function() {
var facade;
iframeUtils.currentWindowId = loc.hash.slice(1);
var onMessage = function(e) {
if (e.source !== parent) {
return;
}
if (typeof parentOrigin === "undefined") {
parentOrigin = e.origin;
}
if (e.origin !== parentOrigin) {
return;
}
var iframeMessage;
try {
iframeMessage = JSON.parse(e.data);
} catch (ignored) {
debug("bad json", e.data);
return;
}
if (iframeMessage.windowId !== iframeUtils.currentWindowId) {
return;
}
switch (iframeMessage.type) {
case "s":
var p;
try {
p = JSON.parse(iframeMessage.data);
} catch (ignored) {
debug("bad json", iframeMessage.data);
break;
}
var version = p[0];
var transport = p[1];
var transUrl = p[2];
var baseUrl = p[3];
debug(version, transport, transUrl, baseUrl);
if (version !== SockJS.version) {
throw new Error('Incompatible SockJS! Main site uses: "' + version + '", the iframe: "' + SockJS.version + '".');
}
if (!urlUtils.isOriginEqual(transUrl, loc.href) || !urlUtils.isOriginEqual(baseUrl, loc.href)) {
throw new Error("Can't connect to different domain from within an iframe. (" + loc.href + ", " + transUrl + ", " + baseUrl + ")");
}
facade = new FacadeJS(new transportMap[transport](transUrl, baseUrl));
break;
case "m":
facade._send(iframeMessage.data);
break;
case "c":
if (facade) {
facade._close();
}
facade = null;
break;
}
};
eventUtils.attachEvent("message", onMessage);
iframeUtils.postMessage("s");
};
};
}).call(this);
}).call(this, { env: {} });
}, { "./facade": 7, "./info-iframe-receiver": 10, "./location": 13, "./utils/event": 46, "./utils/iframe": 47, "./utils/url": 52, "debug": 55 }], 9: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var EventEmitter = require2("events").EventEmitter, inherits = require2("inherits"), objectUtils = require2("./utils/object");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:info-ajax");
}
function InfoAjax(url, AjaxObject) {
EventEmitter.call(this);
var self2 = this;
var t0 = +/* @__PURE__ */ new Date();
this.xo = new AjaxObject("GET", url);
this.xo.once("finish", function(status, text) {
var info, rtt;
if (status === 200) {
rtt = +/* @__PURE__ */ new Date() - t0;
if (text) {
try {
info = JSON.parse(text);
} catch (e) {
debug("bad json", text);
}
}
if (!objectUtils.isObject(info)) {
info = {};
}
}
self2.emit("finish", info, rtt);
self2.removeAllListeners();
});
}
inherits(InfoAjax, EventEmitter);
InfoAjax.prototype.close = function() {
this.removeAllListeners();
this.xo.close();
};
module3.exports = InfoAjax;
}).call(this);
}).call(this, { env: {} });
}, { "./utils/object": 49, "debug": 55, "events": 3, "inherits": 57 }], 10: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter, XHRLocalObject = require2("./transport/sender/xhr-local"), InfoAjax = require2("./info-ajax");
function InfoReceiverIframe(transUrl) {
var self2 = this;
EventEmitter.call(this);
this.ir = new InfoAjax(transUrl, XHRLocalObject);
this.ir.once("finish", function(info, rtt) {
self2.ir = null;
self2.emit("message", JSON.stringify([info, rtt]));
});
}
inherits(InfoReceiverIframe, EventEmitter);
InfoReceiverIframe.transportName = "iframe-info-receiver";
InfoReceiverIframe.prototype.close = function() {
if (this.ir) {
this.ir.close();
this.ir = null;
}
this.removeAllListeners();
};
module3.exports = InfoReceiverIframe;
}, { "./info-ajax": 9, "./transport/sender/xhr-local": 37, "events": 3, "inherits": 57 }], 11: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
var EventEmitter = require2("events").EventEmitter, inherits = require2("inherits"), utils = require2("./utils/event"), IframeTransport = require2("./transport/iframe"), InfoReceiverIframe = require2("./info-iframe-receiver");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:info-iframe");
}
function InfoIframe(baseUrl, url) {
var self2 = this;
EventEmitter.call(this);
var go = function() {
var ifr = self2.ifr = new IframeTransport(InfoReceiverIframe.transportName, url, baseUrl);
ifr.once("message", function(msg) {
if (msg) {
var d;
try {
d = JSON.parse(msg);
} catch (e) {
debug("bad json", msg);
self2.emit("finish");
self2.close();
return;
}
var info = d[0], rtt = d[1];
self2.emit("finish", info, rtt);
}
self2.close();
});
ifr.once("close", function() {
self2.emit("finish");
self2.close();
});
};
if (!global2.document.body) {
utils.attachEvent("load", go);
} else {
go();
}
}
inherits(InfoIframe, EventEmitter);
InfoIframe.enabled = function() {
return IframeTransport.enabled();
};
InfoIframe.prototype.close = function() {
if (this.ifr) {
this.ifr.close();
}
this.removeAllListeners();
this.ifr = null;
};
module3.exports = InfoIframe;
}).call(this);
}).call(this, { env: {} }, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "./info-iframe-receiver": 10, "./transport/iframe": 22, "./utils/event": 46, "debug": 55, "events": 3, "inherits": 57 }], 12: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var EventEmitter = require2("events").EventEmitter, inherits = require2("inherits"), urlUtils = require2("./utils/url"), XDR = require2("./transport/sender/xdr"), XHRCors = require2("./transport/sender/xhr-cors"), XHRLocal = require2("./transport/sender/xhr-local"), XHRFake = require2("./transport/sender/xhr-fake"), InfoIframe = require2("./info-iframe"), InfoAjax = require2("./info-ajax");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:info-receiver");
}
function InfoReceiver(baseUrl, urlInfo) {
debug(baseUrl);
var self2 = this;
EventEmitter.call(this);
setTimeout(function() {
self2.doXhr(baseUrl, urlInfo);
}, 0);
}
inherits(InfoReceiver, EventEmitter);
InfoReceiver._getReceiver = function(baseUrl, url, urlInfo) {
if (urlInfo.sameOrigin) {
return new InfoAjax(url, XHRLocal);
}
if (XHRCors.enabled) {
return new InfoAjax(url, XHRCors);
}
if (XDR.enabled && urlInfo.sameScheme) {
return new InfoAjax(url, XDR);
}
if (InfoIframe.enabled()) {
return new InfoIframe(baseUrl, url);
}
return new InfoAjax(url, XHRFake);
};
InfoReceiver.prototype.doXhr = function(baseUrl, urlInfo) {
var self2 = this, url = urlUtils.addPath(baseUrl, "/info");
debug("doXhr", url);
this.xo = InfoReceiver._getReceiver(baseUrl, url, urlInfo);
this.timeoutRef = setTimeout(function() {
debug("timeout");
self2._cleanup(false);
self2.emit("finish");
}, InfoReceiver.timeout);
this.xo.once("finish", function(info, rtt) {
debug("finish", info, rtt);
self2._cleanup(true);
self2.emit("finish", info, rtt);
});
};
InfoReceiver.prototype._cleanup = function(wasClean) {
debug("_cleanup");
clearTimeout(this.timeoutRef);
this.timeoutRef = null;
if (!wasClean && this.xo) {
this.xo.close();
}
this.xo = null;
};
InfoReceiver.prototype.close = function() {
debug("close");
this.removeAllListeners();
this._cleanup(false);
};
InfoReceiver.timeout = 8e3;
module3.exports = InfoReceiver;
}).call(this);
}).call(this, { env: {} });
}, { "./info-ajax": 9, "./info-iframe": 11, "./transport/sender/xdr": 34, "./transport/sender/xhr-cors": 35, "./transport/sender/xhr-fake": 36, "./transport/sender/xhr-local": 37, "./utils/url": 52, "debug": 55, "events": 3, "inherits": 57 }], 13: [function(require2, module3, exports3) {
(function(global2) {
(function() {
"use strict";
module3.exports = global2.location || {
origin: "http://localhost:80",
protocol: "http:",
host: "localhost",
port: 80,
href: "http://localhost/",
hash: ""
};
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, {}], 14: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
require2("./shims");
var URL = require2("url-parse"), inherits = require2("inherits"), random = require2("./utils/random"), escape = require2("./utils/escape"), urlUtils = require2("./utils/url"), eventUtils = require2("./utils/event"), transport = require2("./utils/transport"), objectUtils = require2("./utils/object"), browser = require2("./utils/browser"), log = require2("./utils/log"), Event = require2("./event/event"), EventTarget = require2("./event/eventtarget"), loc = require2("./location"), CloseEvent = require2("./event/close"), TransportMessageEvent = require2("./event/trans-message"), InfoReceiver = require2("./info-receiver");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:main");
}
var transports;
function SockJS(url, protocols, options) {
if (!(this instanceof SockJS)) {
return new SockJS(url, protocols, options);
}
if (arguments.length < 1) {
throw new TypeError("Failed to construct 'SockJS: 1 argument required, but only 0 present");
}
EventTarget.call(this);
this.readyState = SockJS.CONNECTING;
this.extensions = "";
this.protocol = "";
options = options || {};
if (options.protocols_whitelist) {
log.warn("'protocols_whitelist' is DEPRECATED. Use 'transports' instead.");
}
this._transportsWhitelist = options.transports;
this._transportOptions = options.transportOptions || {};
this._timeout = options.timeout || 0;
var sessionId = options.sessionId || 8;
if (typeof sessionId === "function") {
this._generateSessionId = sessionId;
} else if (typeof sessionId === "number") {
this._generateSessionId = function() {
return random.string(sessionId);
};
} else {
throw new TypeError("If sessionId is used in the options, it needs to be a number or a function.");
}
this._server = options.server || random.numberString(1e3);
var parsedUrl = new URL(url);
if (!parsedUrl.host || !parsedUrl.protocol) {
throw new SyntaxError("The URL '" + url + "' is invalid");
} else if (parsedUrl.hash) {
throw new SyntaxError("The URL must not contain a fragment");
} else if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
throw new SyntaxError("The URL's scheme must be either 'http:' or 'https:'. '" + parsedUrl.protocol + "' is not allowed.");
}
var secure = parsedUrl.protocol === "https:";
if (loc.protocol === "https:" && !secure) {
if (!urlUtils.isLoopbackAddr(parsedUrl.hostname)) {
throw new Error("SecurityError: An insecure SockJS connection may not be initiated from a page loaded over HTTPS");
}
}
if (!protocols) {
protocols = [];
} else if (!Array.isArray(protocols)) {
protocols = [protocols];
}
var sortedProtocols = protocols.sort();
sortedProtocols.forEach(function(proto, i) {
if (!proto) {
throw new SyntaxError("The protocols entry '" + proto + "' is invalid.");
}
if (i < sortedProtocols.length - 1 && proto === sortedProtocols[i + 1]) {
throw new SyntaxError("The protocols entry '" + proto + "' is duplicated.");
}
});
var o = urlUtils.getOrigin(loc.href);
this._origin = o ? o.toLowerCase() : null;
parsedUrl.set("pathname", parsedUrl.pathname.replace(/\/+$/, ""));
this.url = parsedUrl.href;
debug("using url", this.url);
this._urlInfo = {
nullOrigin: !browser.hasDomain(),
sameOrigin: urlUtils.isOriginEqual(this.url, loc.href),
sameScheme: urlUtils.isSchemeEqual(this.url, loc.href)
};
this._ir = new InfoReceiver(this.url, this._urlInfo);
this._ir.once("finish", this._receiveInfo.bind(this));
}
inherits(SockJS, EventTarget);
function userSetCode(code) {
return code === 1e3 || code >= 3e3 && code <= 4999;
}
SockJS.prototype.close = function(code, reason) {
if (code && !userSetCode(code)) {
throw new Error("InvalidAccessError: Invalid code");
}
if (reason && reason.length > 123) {
throw new SyntaxError("reason argument has an invalid length");
}
if (this.readyState === SockJS.CLOSING || this.readyState === SockJS.CLOSED) {
return;
}
var wasClean = true;
this._close(code || 1e3, reason || "Normal closure", wasClean);
};
SockJS.prototype.send = function(data) {
if (typeof data !== "string") {
data = "" + data;
}
if (this.readyState === SockJS.CONNECTING) {
throw new Error("InvalidStateError: The connection has not been established yet");
}
if (this.readyState !== SockJS.OPEN) {
return;
}
this._transport.send(escape.quote(data));
};
SockJS.version = require2("./version");
SockJS.CONNECTING = 0;
SockJS.OPEN = 1;
SockJS.CLOSING = 2;
SockJS.CLOSED = 3;
SockJS.prototype._receiveInfo = function(info, rtt) {
debug("_receiveInfo", rtt);
this._ir = null;
if (!info) {
this._close(1002, "Cannot connect to server");
return;
}
this._rto = this.countRTO(rtt);
this._transUrl = info.base_url ? info.base_url : this.url;
info = objectUtils.extend(info, this._urlInfo);
debug("info", info);
var enabledTransports = transports.filterToEnabled(this._transportsWhitelist, info);
this._transports = enabledTransports.main;
debug(this._transports.length + " enabled transports");
this._connect();
};
SockJS.prototype._connect = function() {
for (var Transport = this._transports.shift(); Transport; Transport = this._transports.shift()) {
debug("attempt", Transport.transportName);
if (Transport.needBody) {
if (!global2.document.body || typeof global2.document.readyState !== "undefined" && global2.document.readyState !== "complete" && global2.document.readyState !== "interactive") {
debug("waiting for body");
this._transports.unshift(Transport);
eventUtils.attachEvent("load", this._connect.bind(this));
return;
}
}
var timeoutMs = Math.max(this._timeout, this._rto * Transport.roundTrips || 5e3);
this._transportTimeoutId = setTimeout(this._transportTimeout.bind(this), timeoutMs);
debug("using timeout", timeoutMs);
var transportUrl = urlUtils.addPath(this._transUrl, "/" + this._server + "/" + this._generateSessionId());
var options = this._transportOptions[Transport.transportName];
debug("transport url", transportUrl);
var transportObj = new Transport(transportUrl, this._transUrl, options);
transportObj.on("message", this._transportMessage.bind(this));
transportObj.once("close", this._transportClose.bind(this));
transportObj.transportName = Transport.transportName;
this._transport = transportObj;
return;
}
this._close(2e3, "All transports failed", false);
};
SockJS.prototype._transportTimeout = function() {
debug("_transportTimeout");
if (this.readyState === SockJS.CONNECTING) {
if (this._transport) {
this._transport.close();
}
this._transportClose(2007, "Transport timed out");
}
};
SockJS.prototype._transportMessage = function(msg) {
debug("_transportMessage", msg);
var self2 = this, type = msg.slice(0, 1), content = msg.slice(1), payload;
switch (type) {
case "o":
this._open();
return;
case "h":
this.dispatchEvent(new Event("heartbeat"));
debug("heartbeat", this.transport);
return;
}
if (content) {
try {
payload = JSON.parse(content);
} catch (e) {
debug("bad json", content);
}
}
if (typeof payload === "undefined") {
debug("empty payload", content);
return;
}
switch (type) {
case "a":
if (Array.isArray(payload)) {
payload.forEach(function(p) {
debug("message", self2.transport, p);
self2.dispatchEvent(new TransportMessageEvent(p));
});
}
break;
case "m":
debug("message", this.transport, payload);
this.dispatchEvent(new TransportMessageEvent(payload));
break;
case "c":
if (Array.isArray(payload) && payload.length === 2) {
this._close(payload[0], payload[1], true);
}
break;
}
};
SockJS.prototype._transportClose = function(code, reason) {
debug("_transportClose", this.transport, code, reason);
if (this._transport) {
this._transport.removeAllListeners();
this._transport = null;
this.transport = null;
}
if (!userSetCode(code) && code !== 2e3 && this.readyState === SockJS.CONNECTING) {
this._connect();
return;
}
this._close(code, reason);
};
SockJS.prototype._open = function() {
debug("_open", this._transport && this._transport.transportName, this.readyState);
if (this.readyState === SockJS.CONNECTING) {
if (this._transportTimeoutId) {
clearTimeout(this._transportTimeoutId);
this._transportTimeoutId = null;
}
this.readyState = SockJS.OPEN;
this.transport = this._transport.transportName;
this.dispatchEvent(new Event("open"));
debug("connected", this.transport);
} else {
this._close(1006, "Server lost session");
}
};
SockJS.prototype._close = function(code, reason, wasClean) {
debug("_close", this.transport, code, reason, wasClean, this.readyState);
var forceFail = false;
if (this._ir) {
forceFail = true;
this._ir.close();
this._ir = null;
}
if (this._transport) {
this._transport.close();
this._transport = null;
this.transport = null;
}
if (this.readyState === SockJS.CLOSED) {
throw new Error("InvalidStateError: SockJS has already been closed");
}
this.readyState = SockJS.CLOSING;
setTimeout(function() {
this.readyState = SockJS.CLOSED;
if (forceFail) {
this.dispatchEvent(new Event("error"));
}
var e = new CloseEvent("close");
e.wasClean = wasClean || false;
e.code = code || 1e3;
e.reason = reason;
this.dispatchEvent(e);
this.onmessage = this.onclose = this.onerror = null;
debug("disconnected");
}.bind(this), 0);
};
SockJS.prototype.countRTO = function(rtt) {
if (rtt > 100) {
return 4 * rtt;
}
return 300 + rtt;
};
module3.exports = function(availableTransports) {
transports = transport(availableTransports);
require2("./iframe-bootstrap")(SockJS, availableTransports);
return SockJS;
};
}).call(this);
}).call(this, { env: {} }, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "./event/close": 2, "./event/event": 4, "./event/eventtarget": 5, "./event/trans-message": 6, "./iframe-bootstrap": 8, "./info-receiver": 12, "./location": 13, "./shims": 15, "./utils/browser": 44, "./utils/escape": 45, "./utils/event": 46, "./utils/log": 48, "./utils/object": 49, "./utils/random": 50, "./utils/transport": 51, "./utils/url": 52, "./version": 53, "debug": 55, "inherits": 57, "url-parse": 60 }], 15: [function(require2, module3, exports3) {
"use strict";
var ArrayPrototype = Array.prototype;
var ObjectPrototype = Object.prototype;
var FunctionPrototype = Function.prototype;
var StringPrototype = String.prototype;
var array_slice = ArrayPrototype.slice;
var _toString = ObjectPrototype.toString;
var isFunction = function(val) {
return ObjectPrototype.toString.call(val) === "[object Function]";
};
var isArray = function isArray2(obj) {
return _toString.call(obj) === "[object Array]";
};
var isString = function isString2(obj) {
return _toString.call(obj) === "[object String]";
};
var supportsDescriptors = Object.defineProperty && function() {
try {
Object.defineProperty({}, "x", {});
return true;
} catch (e) {
return false;
}
}();
var defineProperty;
if (supportsDescriptors) {
defineProperty = function(object, name, method, forceAssign) {
if (!forceAssign && name in object) {
return;
}
Object.defineProperty(object, name, {
configurable: true,
enumerable: false,
writable: true,
value: method
});
};
} else {
defineProperty = function(object, name, method, forceAssign) {
if (!forceAssign && name in object) {
return;
}
object[name] = method;
};
}
var defineProperties = function(object, map, forceAssign) {
for (var name in map) {
if (ObjectPrototype.hasOwnProperty.call(map, name)) {
defineProperty(object, name, map[name], forceAssign);
}
}
};
var toObject = function(o) {
if (o == null) {
throw new TypeError("can't convert " + o + " to object");
}
return Object(o);
};
function toInteger(num) {
var n = +num;
if (n !== n) {
n = 0;
} else if (n !== 0 && n !== 1 / 0 && n !== -(1 / 0)) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
return n;
}
function ToUint32(x) {
return x >>> 0;
}
function Empty() {
}
defineProperties(FunctionPrototype, {
bind: function bind(that) {
var target = this;
if (!isFunction(target)) {
throw new TypeError("Function.prototype.bind called on incompatible " + target);
}
var args = array_slice.call(arguments, 1);
var binder = function() {
if (this instanceof bound) {
var result = target.apply(
this,
args.concat(array_slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return this;
} else {
return target.apply(
that,
args.concat(array_slice.call(arguments))
);
}
};
var boundLength = Math.max(0, target.length - args.length);
var boundArgs = [];
for (var i = 0; i < boundLength; i++) {
boundArgs.push("$" + i);
}
var bound = Function("binder", "return function (" + boundArgs.join(",") + "){ return binder.apply(this, arguments); }")(binder);
if (target.prototype) {
Empty.prototype = target.prototype;
bound.prototype = new Empty();
Empty.prototype = null;
}
return bound;
}
});
defineProperties(Array, { isArray });
var boxedString = Object("a");
var splitString = boxedString[0] !== "a" || !(0 in boxedString);
var properlyBoxesContext = function properlyBoxed(method) {
var properlyBoxesNonStrict = true;
var properlyBoxesStrict = true;
if (method) {
method.call("foo", function(_, __, context) {
if (typeof context !== "object") {
properlyBoxesNonStrict = false;
}
});
method.call([1], function() {
"use strict";
properlyBoxesStrict = typeof this === "string";
}, "x");
}
return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
};
defineProperties(ArrayPrototype, {
forEach: function forEach(fun) {
var object = toObject(this), self2 = splitString && isString(this) ? this.split("") : object, thisp = arguments[1], i = -1, length = self2.length >>> 0;
if (!isFunction(fun)) {
throw new TypeError();
}
while (++i < length) {
if (i in self2) {
fun.call(thisp, self2[i], i, object);
}
}
}
}, !properlyBoxesContext(ArrayPrototype.forEach));
var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
defineProperties(ArrayPrototype, {
indexOf: function indexOf(sought) {
var self2 = splitString && isString(this) ? this.split("") : toObject(this), length = self2.length >>> 0;
if (!length) {
return -1;
}
var i = 0;
if (arguments.length > 1) {
i = toInteger(arguments[1]);
}
i = i >= 0 ? i : Math.max(0, length + i);
for (; i < length; i++) {
if (i in self2 && self2[i] === sought) {
return i;
}
}
return -1;
}
}, hasFirefox2IndexOfBug);
var string_split = StringPrototype.split;
if ("ab".split(/(?:ab)*/).length !== 2 || ".".split(/(.?)(.?)/).length !== 4 || "tesst".split(/(s)*/)[1] === "t" || "test".split(/(?:)/, -1).length !== 4 || "".split(/.?/).length || ".".split(/()()/).length > 1) {
(function() {
var compliantExecNpcg = /()??/.exec("")[1] === void 0;
StringPrototype.split = function(separator, limit) {
var string = this;
if (separator === void 0 && limit === 0) {
return [];
}
if (_toString.call(separator) !== "[object RegExp]") {
return string_split.call(this, separator, limit);
}
var output = [], flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
(separator.sticky ? "y" : ""), lastLastIndex = 0, separator2, match, lastIndex, lastLength;
separator = new RegExp(separator.source, flags + "g");
string += "";
if (!compliantExecNpcg) {
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
}
limit = limit === void 0 ? -1 >>> 0 : (
// Math.pow(2, 32) - 1
ToUint32(limit)
);
while (match = separator.exec(string)) {
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
output.push(string.slice(lastLastIndex, match.index));
if (!compliantExecNpcg && match.length > 1) {
match[0].replace(separator2, function() {
for (var i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === void 0) {
match[i] = void 0;
}
}
});
}
if (match.length > 1 && match.index < string.length) {
ArrayPrototype.push.apply(output, match.slice(1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= limit) {
break;
}
}
if (separator.lastIndex === match.index) {
separator.lastIndex++;
}
}
if (lastLastIndex === string.length) {
if (lastLength || !separator.test("")) {
output.push("");
}
} else {
output.push(string.slice(lastLastIndex));
}
return output.length > limit ? output.slice(0, limit) : output;
};
})();
} else if ("0".split(void 0, 0).length) {
StringPrototype.split = function split(separator, limit) {
if (separator === void 0 && limit === 0) {
return [];
}
return string_split.call(this, separator, limit);
};
}
var string_substr = StringPrototype.substr;
var hasNegativeSubstrBug = "".substr && "0b".substr(-1) !== "b";
defineProperties(StringPrototype, {
substr: function substr(start, length) {
return string_substr.call(
this,
start < 0 ? (start = this.length + start) < 0 ? 0 : start : start,
length
);
}
}, hasNegativeSubstrBug);
}, {}], 16: [function(require2, module3, exports3) {
"use strict";
module3.exports = [
// streaming transports
require2("./transport/websocket"),
require2("./transport/xhr-streaming"),
require2("./transport/xdr-streaming"),
require2("./transport/eventsource"),
require2("./transport/lib/iframe-wrap")(require2("./transport/eventsource")),
require2("./transport/htmlfile"),
require2("./transport/lib/iframe-wrap")(require2("./transport/htmlfile")),
require2("./transport/xhr-polling"),
require2("./transport/xdr-polling"),
require2("./transport/lib/iframe-wrap")(require2("./transport/xhr-polling")),
require2("./transport/jsonp-polling")
];
}, { "./transport/eventsource": 20, "./transport/htmlfile": 21, "./transport/jsonp-polling": 23, "./transport/lib/iframe-wrap": 26, "./transport/websocket": 38, "./transport/xdr-polling": 39, "./transport/xdr-streaming": 40, "./transport/xhr-polling": 41, "./transport/xhr-streaming": 42 }], 17: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
var EventEmitter = require2("events").EventEmitter, inherits = require2("inherits"), utils = require2("../../utils/event"), urlUtils = require2("../../utils/url"), XHR = global2.XMLHttpRequest;
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:browser:xhr");
}
function AbstractXHRObject(method, url, payload, opts) {
debug(method, url);
var self2 = this;
EventEmitter.call(this);
setTimeout(function() {
self2._start(method, url, payload, opts);
}, 0);
}
inherits(AbstractXHRObject, EventEmitter);
AbstractXHRObject.prototype._start = function(method, url, payload, opts) {
var self2 = this;
try {
this.xhr = new XHR();
} catch (x) {
}
if (!this.xhr) {
debug("no xhr");
this.emit("finish", 0, "no xhr support");
this._cleanup();
return;
}
url = urlUtils.addQuery(url, "t=" + +/* @__PURE__ */ new Date());
this.unloadRef = utils.unloadAdd(function() {
debug("unload cleanup");
self2._cleanup(true);
});
try {
this.xhr.open(method, url, true);
if (this.timeout && "timeout" in this.xhr) {
this.xhr.timeout = this.timeout;
this.xhr.ontimeout = function() {
debug("xhr timeout");
self2.emit("finish", 0, "");
self2._cleanup(false);
};
}
} catch (e) {
debug("exception", e);
this.emit("finish", 0, "");
this._cleanup(false);
return;
}
if ((!opts || !opts.noCredentials) && AbstractXHRObject.supportsCORS) {
debug("withCredentials");
this.xhr.withCredentials = true;
}
if (opts && opts.headers) {
for (var key in opts.headers) {
this.xhr.setRequestHeader(key, opts.headers[key]);
}
}
this.xhr.onreadystatechange = function() {
if (self2.xhr) {
var x = self2.xhr;
var text, status;
debug("readyState", x.readyState);
switch (x.readyState) {
case 3:
try {
status = x.status;
text = x.responseText;
} catch (e) {
}
debug("status", status);
if (status === 1223) {
status = 204;
}
if (status === 200 && text && text.length > 0) {
debug("chunk");
self2.emit("chunk", status, text);
}
break;
case 4:
status = x.status;
debug("status", status);
if (status === 1223) {
status = 204;
}
if (status === 12005 || status === 12029) {
status = 0;
}
debug("finish", status, x.responseText);
self2.emit("finish", status, x.responseText);
self2._cleanup(false);
break;
}
}
};
try {
self2.xhr.send(payload);
} catch (e) {
self2.emit("finish", 0, "");
self2._cleanup(false);
}
};
AbstractXHRObject.prototype._cleanup = function(abort) {
debug("cleanup");
if (!this.xhr) {
return;
}
this.removeAllListeners();
utils.unloadDel(this.unloadRef);
this.xhr.onreadystatechange = function() {
};
if (this.xhr.ontimeout) {
this.xhr.ontimeout = null;
}
if (abort) {
try {
this.xhr.abort();
} catch (x) {
}
}
this.unloadRef = this.xhr = null;
};
AbstractXHRObject.prototype.close = function() {
debug("close");
this._cleanup(true);
};
AbstractXHRObject.enabled = !!XHR;
var axo = ["Active"].concat("Object").join("X");
if (!AbstractXHRObject.enabled && axo in global2) {
debug("overriding xmlhttprequest");
XHR = function() {
try {
return new global2[axo]("Microsoft.XMLHTTP");
} catch (e) {
return null;
}
};
AbstractXHRObject.enabled = !!new XHR();
}
var cors = false;
try {
cors = "withCredentials" in new XHR();
} catch (ignored) {
}
AbstractXHRObject.supportsCORS = cors;
module3.exports = AbstractXHRObject;
}).call(this);
}).call(this, { env: {} }, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "../../utils/event": 46, "../../utils/url": 52, "debug": 55, "events": 3, "inherits": 57 }], 18: [function(require2, module3, exports3) {
(function(global2) {
(function() {
module3.exports = global2.EventSource;
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, {}], 19: [function(require2, module3, exports3) {
(function(global2) {
(function() {
"use strict";
var Driver = global2.WebSocket || global2.MozWebSocket;
if (Driver) {
module3.exports = function WebSocketBrowserDriver(url) {
return new Driver(url);
};
} else {
module3.exports = void 0;
}
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, {}], 20: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), AjaxBasedTransport = require2("./lib/ajax-based"), EventSourceReceiver = require2("./receiver/eventsource"), XHRCorsObject = require2("./sender/xhr-cors"), EventSourceDriver = require2("eventsource");
function EventSourceTransport(transUrl) {
if (!EventSourceTransport.enabled()) {
throw new Error("Transport created when disabled");
}
AjaxBasedTransport.call(this, transUrl, "/eventsource", EventSourceReceiver, XHRCorsObject);
}
inherits(EventSourceTransport, AjaxBasedTransport);
EventSourceTransport.enabled = function() {
return !!EventSourceDriver;
};
EventSourceTransport.transportName = "eventsource";
EventSourceTransport.roundTrips = 2;
module3.exports = EventSourceTransport;
}, { "./lib/ajax-based": 24, "./receiver/eventsource": 29, "./sender/xhr-cors": 35, "eventsource": 18, "inherits": 57 }], 21: [function(require2, module3, exports3) {
"use strict";
var inherits = require2("inherits"), HtmlfileReceiver = require2("./receiver/htmlfile"), XHRLocalObject = require2("./sender/xhr-local"), AjaxBasedTransport = require2("./lib/ajax-based");
function HtmlFileTransport(transUrl) {
if (!HtmlfileReceiver.enabled) {
throw new Error("Transport created when disabled");
}
AjaxBasedTransport.call(this, transUrl, "/htmlfile", HtmlfileReceiver, XHRLocalObject);
}
inherits(HtmlFileTransport, AjaxBasedTransport);
HtmlFileTransport.enabled = function(info) {
return HtmlfileReceiver.enabled && info.sameOrigin;
};
HtmlFileTransport.transportName = "htmlfile";
HtmlFileTransport.roundTrips = 2;
module3.exports = HtmlFileTransport;
}, { "./lib/ajax-based": 24, "./receiver/htmlfile": 30, "./sender/xhr-local": 37, "inherits": 57 }], 22: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter, version = require2("../version"), urlUtils = require2("../utils/url"), iframeUtils = require2("../utils/iframe"), eventUtils = require2("../utils/event"), random = require2("../utils/random");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:transport:iframe");
}
function IframeTransport(transport, transUrl, baseUrl) {
if (!IframeTransport.enabled()) {
throw new Error("Transport created when disabled");
}
EventEmitter.call(this);
var self2 = this;
this.origin = urlUtils.getOrigin(baseUrl);
this.baseUrl = baseUrl;
this.transUrl = transUrl;
this.transport = transport;
this.windowId = random.string(8);
var iframeUrl = urlUtils.addPath(baseUrl, "/iframe.html") + "#" + this.windowId;
debug(transport, transUrl, iframeUrl);
this.iframeObj = iframeUtils.createIframe(iframeUrl, function(r) {
debug("err callback");
self2.emit("close", 1006, "Unable to load an iframe (" + r + ")");
self2.close();
});
this.onmessageCallback = this._message.bind(this);
eventUtils.attachEvent("message", this.onmessageCallback);
}
inherits(IframeTransport, EventEmitter);
IframeTransport.prototype.close = function() {
debug("close");
this.removeAllListeners();
if (this.iframeObj) {
eventUtils.detachEvent("message", this.onmessageCallback);
try {
this.postMessage("c");
} catch (x) {
}
this.iframeObj.cleanup();
this.iframeObj = null;
this.onmessageCallback = this.iframeObj = null;
}
};
IframeTransport.prototype._message = function(e) {
debug("message", e.data);
if (!urlUtils.isOriginEqual(e.origin, this.origin)) {
debug("not same origin", e.origin, this.origin);
return;
}
var iframeMessage;
try {
iframeMessage = JSON.parse(e.data);
} catch (ignored) {
debug("bad json", e.data);
return;
}
if (iframeMessage.windowId !== this.windowId) {
debug("mismatched window id", iframeMessage.windowId, this.windowId);
return;
}
switch (iframeMessage.type) {
case "s":
this.iframeObj.loaded();
this.postMessage("s", JSON.stringify([
version,
this.transport,
this.transUrl,
this.baseUrl
]));
break;
case "t":
this.emit("message", iframeMessage.data);
break;
case "c":
var cdata;
try {
cdata = JSON.parse(iframeMessage.data);
} catch (ignored) {
debug("bad json", iframeMessage.data);
return;
}
this.emit("close", cdata[0], cdata[1]);
this.close();
break;
}
};
IframeTransport.prototype.postMessage = function(type, data) {
debug("postMessage", type, data);
this.iframeObj.post(JSON.stringify({
windowId: this.windowId,
type,
data: data || ""
}), this.origin);
};
IframeTransport.prototype.send = function(message) {
debug("send", message);
this.postMessage("m", message);
};
IframeTransport.enabled = function() {
return iframeUtils.iframeEnabled;
};
IframeTransport.transportName = "iframe";
IframeTransport.roundTrips = 2;
module3.exports = IframeTransport;
}).call(this);
}).call(this, { env: {} });
}, { "../utils/event": 46, "../utils/iframe": 47, "../utils/random": 50, "../utils/url": 52, "../version": 53, "debug": 55, "events": 3, "inherits": 57 }], 23: [function(require2, module3, exports3) {
(function(global2) {
(function() {
"use strict";
var inherits = require2("inherits"), SenderReceiver = require2("./lib/sender-receiver"), JsonpReceiver = require2("./receiver/jsonp"), jsonpSender = require2("./sender/jsonp");
function JsonPTransport(transUrl) {
if (!JsonPTransport.enabled()) {
throw new Error("Transport created when disabled");
}
SenderReceiver.call(this, transUrl, "/jsonp", jsonpSender, JsonpReceiver);
}
inherits(JsonPTransport, SenderReceiver);
JsonPTransport.enabled = function() {
return !!global2.document;
};
JsonPTransport.transportName = "jsonp-polling";
JsonPTransport.roundTrips = 1;
JsonPTransport.needBody = true;
module3.exports = JsonPTransport;
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "./lib/sender-receiver": 28, "./receiver/jsonp": 31, "./sender/jsonp": 33, "inherits": 57 }], 24: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), urlUtils = require2("../../utils/url"), SenderReceiver = require2("./sender-receiver");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:ajax-based");
}
function createAjaxSender(AjaxObject) {
return function(url, payload, callback) {
debug("create ajax sender", url, payload);
var opt = {};
if (typeof payload === "string") {
opt.headers = { "Content-type": "text/plain" };
}
var ajaxUrl = urlUtils.addPath(url, "/xhr_send");
var xo = new AjaxObject("POST", ajaxUrl, payload, opt);
xo.once("finish", function(status) {
debug("finish", status);
xo = null;
if (status !== 200 && status !== 204) {
return callback(new Error("http status " + status));
}
callback();
});
return function() {
debug("abort");
xo.close();
xo = null;
var err = new Error("Aborted");
err.code = 1e3;
callback(err);
};
};
}
function AjaxBasedTransport(transUrl, urlSuffix, Receiver, AjaxObject) {
SenderReceiver.call(this, transUrl, urlSuffix, createAjaxSender(AjaxObject), Receiver, AjaxObject);
}
inherits(AjaxBasedTransport, SenderReceiver);
module3.exports = AjaxBasedTransport;
}).call(this);
}).call(this, { env: {} });
}, { "../../utils/url": 52, "./sender-receiver": 28, "debug": 55, "inherits": 57 }], 25: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter;
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:buffered-sender");
}
function BufferedSender(url, sender) {
debug(url);
EventEmitter.call(this);
this.sendBuffer = [];
this.sender = sender;
this.url = url;
}
inherits(BufferedSender, EventEmitter);
BufferedSender.prototype.send = function(message) {
debug("send", message);
this.sendBuffer.push(message);
if (!this.sendStop) {
this.sendSchedule();
}
};
BufferedSender.prototype.sendScheduleWait = function() {
debug("sendScheduleWait");
var self2 = this;
var tref;
this.sendStop = function() {
debug("sendStop");
self2.sendStop = null;
clearTimeout(tref);
};
tref = setTimeout(function() {
debug("timeout");
self2.sendStop = null;
self2.sendSchedule();
}, 25);
};
BufferedSender.prototype.sendSchedule = function() {
debug("sendSchedule", this.sendBuffer.length);
var self2 = this;
if (this.sendBuffer.length > 0) {
var payload = "[" + this.sendBuffer.join(",") + "]";
this.sendStop = this.sender(this.url, payload, function(err) {
self2.sendStop = null;
if (err) {
debug("error", err);
self2.emit("close", err.code || 1006, "Sending error: " + err);
self2.close();
} else {
self2.sendScheduleWait();
}
});
this.sendBuffer = [];
}
};
BufferedSender.prototype._cleanup = function() {
debug("_cleanup");
this.removeAllListeners();
};
BufferedSender.prototype.close = function() {
debug("close");
this._cleanup();
if (this.sendStop) {
this.sendStop();
this.sendStop = null;
}
};
module3.exports = BufferedSender;
}).call(this);
}).call(this, { env: {} });
}, { "debug": 55, "events": 3, "inherits": 57 }], 26: [function(require2, module3, exports3) {
(function(global2) {
(function() {
"use strict";
var inherits = require2("inherits"), IframeTransport = require2("../iframe"), objectUtils = require2("../../utils/object");
module3.exports = function(transport) {
function IframeWrapTransport(transUrl, baseUrl) {
IframeTransport.call(this, transport.transportName, transUrl, baseUrl);
}
inherits(IframeWrapTransport, IframeTransport);
IframeWrapTransport.enabled = function(url, info) {
if (!global2.document) {
return false;
}
var iframeInfo = objectUtils.extend({}, info);
iframeInfo.sameOrigin = true;
return transport.enabled(iframeInfo) && IframeTransport.enabled();
};
IframeWrapTransport.transportName = "iframe-" + transport.transportName;
IframeWrapTransport.needBody = true;
IframeWrapTransport.roundTrips = IframeTransport.roundTrips + transport.roundTrips - 1;
IframeWrapTransport.facadeTransport = transport;
return IframeWrapTransport;
};
}).call(this);
}).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "../../utils/object": 49, "../iframe": 22, "inherits": 57 }], 27: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter;
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:polling");
}
function Polling(Receiver, receiveUrl, AjaxObject) {
debug(receiveUrl);
EventEmitter.call(this);
this.Receiver = Receiver;
this.receiveUrl = receiveUrl;
this.AjaxObject = AjaxObject;
this._scheduleReceiver();
}
inherits(Polling, EventEmitter);
Polling.prototype._scheduleReceiver = function() {
debug("_scheduleReceiver");
var self2 = this;
var poll = this.poll = new this.Receiver(this.receiveUrl, this.AjaxObject);
poll.on("message", function(msg) {
debug("message", msg);
self2.emit("message", msg);
});
poll.once("close", function(code, reason) {
debug("close", code, reason, self2.pollIsClosing);
self2.poll = poll = null;
if (!self2.pollIsClosing) {
if (reason === "network") {
self2._scheduleReceiver();
} else {
self2.emit("close", code || 1006, reason);
self2.removeAllListeners();
}
}
});
};
Polling.prototype.abort = function() {
debug("abort");
this.removeAllListeners();
this.pollIsClosing = true;
if (this.poll) {
this.poll.abort();
}
};
module3.exports = Polling;
}).call(this);
}).call(this, { env: {} });
}, { "debug": 55, "events": 3, "inherits": 57 }], 28: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), urlUtils = require2("../../utils/url"), BufferedSender = require2("./buffered-sender"), Polling = require2("./polling");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:sender-receiver");
}
function SenderReceiver(transUrl, urlSuffix, senderFunc, Receiver, AjaxObject) {
var pollUrl = urlUtils.addPath(transUrl, urlSuffix);
debug(pollUrl);
var self2 = this;
BufferedSender.call(this, transUrl, senderFunc);
this.poll = new Polling(Receiver, pollUrl, AjaxObject);
this.poll.on("message", function(msg) {
debug("poll message", msg);
self2.emit("message", msg);
});
this.poll.once("close", function(code, reason) {
debug("poll close", code, reason);
self2.poll = null;
self2.emit("close", code, reason);
self2.close();
});
}
inherits(SenderReceiver, BufferedSender);
SenderReceiver.prototype.close = function() {
BufferedSender.prototype.close.call(this);
debug("close");
this.removeAllListeners();
if (this.poll) {
this.poll.abort();
this.poll = null;
}
};
module3.exports = SenderReceiver;
}).call(this);
}).call(this, { env: {} });
}, { "../../utils/url": 52, "./buffered-sender": 25, "./polling": 27, "debug": 55, "inherits": 57 }], 29: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter, EventSourceDriver = require2("eventsource");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:receiver:eventsource");
}
function EventSourceReceiver(url) {
debug(url);
EventEmitter.call(this);
var self2 = this;
var es = this.es = new EventSourceDriver(url);
es.onmessage = function(e) {
debug("message", e.data);
self2.emit("message", decodeURI(e.data));
};
es.onerror = function(e) {
debug("error", es.readyState, e);
var reason = es.readyState !== 2 ? "network" : "permanent";
self2._cleanup();
self2._close(reason);
};
}
inherits(EventSourceReceiver, EventEmitter);
EventSourceReceiver.prototype.abort = function() {
debug("abort");
this._cleanup();
this._close("user");
};
EventSourceReceiver.prototype._cleanup = function() {
debug("cleanup");
var es = this.es;
if (es) {
es.onmessage = es.onerror = null;
es.close();
this.es = null;
}
};
EventSourceReceiver.prototype._close = function(reason) {
debug("close", reason);
var self2 = this;
setTimeout(function() {
self2.emit("close", null, reason);
self2.removeAllListeners();
}, 200);
};
module3.exports = EventSourceReceiver;
}).call(this);
}).call(this, { env: {} });
}, { "debug": 55, "events": 3, "eventsource": 18, "inherits": 57 }], 30: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
var inherits = require2("inherits"), iframeUtils = require2("../../utils/iframe"), urlUtils = require2("../../utils/url"), EventEmitter = require2("events").EventEmitter, random = require2("../../utils/random");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:receiver:htmlfile");
}
function HtmlfileReceiver(url) {
debug(url);
EventEmitter.call(this);
var self2 = this;
iframeUtils.polluteGlobalNamespace();
this.id = "a" + random.string(6);
url = urlUtils.addQuery(url, "c=" + decodeURIComponent(iframeUtils.WPrefix + "." + this.id));
debug("using htmlfile", HtmlfileReceiver.htmlfileEnabled);
var constructFunc = HtmlfileReceiver.htmlfileEnabled ? iframeUtils.createHtmlfile : iframeUtils.createIframe;
global2[iframeUtils.WPrefix][this.id] = {
start: function() {
debug("start");
self2.iframeObj.loaded();
},
message: function(data) {
debug("message", data);
self2.emit("message", data);
},
stop: function() {
debug("stop");
self2._cleanup();
self2._close("network");
}
};
this.iframeObj = constructFunc(url, function() {
debug("callback");
self2._cleanup();
self2._close("permanent");
});
}
inherits(HtmlfileReceiver, EventEmitter);
HtmlfileReceiver.prototype.abort = function() {
debug("abort");
this._cleanup();
this._close("user");
};
HtmlfileReceiver.prototype._cleanup = function() {
debug("_cleanup");
if (this.iframeObj) {
this.iframeObj.cleanup();
this.iframeObj = null;
}
delete global2[iframeUtils.WPrefix][this.id];
};
HtmlfileReceiver.prototype._close = function(reason) {
debug("_close", reason);
this.emit("close", null, reason);
this.removeAllListeners();
};
HtmlfileReceiver.htmlfileEnabled = false;
var axo = ["Active"].concat("Object").join("X");
if (axo in global2) {
try {
HtmlfileReceiver.htmlfileEnabled = !!new global2[axo]("htmlfile");
} catch (x) {
}
}
HtmlfileReceiver.enabled = HtmlfileReceiver.htmlfileEnabled || iframeUtils.iframeEnabled;
module3.exports = HtmlfileReceiver;
}).call(this);
}).call(this, { env: {} }, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "../../utils/iframe": 47, "../../utils/random": 50, "../../utils/url": 52, "debug": 55, "events": 3, "inherits": 57 }], 31: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
var utils = require2("../../utils/iframe"), random = require2("../../utils/random"), browser = require2("../../utils/browser"), urlUtils = require2("../../utils/url"), inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter;
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:receiver:jsonp");
}
function JsonpReceiver(url) {
debug(url);
var self2 = this;
EventEmitter.call(this);
utils.polluteGlobalNamespace();
this.id = "a" + random.string(6);
var urlWithId = urlUtils.addQuery(url, "c=" + encodeURIComponent(utils.WPrefix + "." + this.id));
global2[utils.WPrefix][this.id] = this._callback.bind(this);
this._createScript(urlWithId);
this.timeoutId = setTimeout(function() {
debug("timeout");
self2._abort(new Error("JSONP script loaded abnormally (timeout)"));
}, JsonpReceiver.timeout);
}
inherits(JsonpReceiver, EventEmitter);
JsonpReceiver.prototype.abort = function() {
debug("abort");
if (global2[utils.WPrefix][this.id]) {
var err = new Error("JSONP user aborted read");
err.code = 1e3;
this._abort(err);
}
};
JsonpReceiver.timeout = 35e3;
JsonpReceiver.scriptErrorTimeout = 1e3;
JsonpReceiver.prototype._callback = function(data) {
debug("_callback", data);
this._cleanup();
if (this.aborting) {
return;
}
if (data) {
debug("message", data);
this.emit("message", data);
}
this.emit("close", null, "network");
this.removeAllListeners();
};
JsonpReceiver.prototype._abort = function(err) {
debug("_abort", err);
this._cleanup();
this.aborting = true;
this.emit("close", err.code, err.message);
this.removeAllListeners();
};
JsonpReceiver.prototype._cleanup = function() {
debug("_cleanup");
clearTimeout(this.timeoutId);
if (this.script2) {
this.script2.parentNode.removeChild(this.script2);
this.script2 = null;
}
if (this.script) {
var script = this.script;
script.parentNode.removeChild(script);
script.onreadystatechange = script.onerror = script.onload = script.onclick = null;
this.script = null;
}
delete global2[utils.WPrefix][this.id];
};
JsonpReceiver.prototype._scriptError = function() {
debug("_scriptError");
var self2 = this;
if (this.errorTimer) {
return;
}
this.errorTimer = setTimeout(function() {
if (!self2.loadedOkay) {
self2._abort(new Error("JSONP script loaded abnormally (onerror)"));
}
}, JsonpReceiver.scriptErrorTimeout);
};
JsonpReceiver.prototype._createScript = function(url) {
debug("_createScript", url);
var self2 = this;
var script = this.script = global2.document.createElement("script");
var script2;
script.id = "a" + random.string(8);
script.src = url;
script.type = "text/javascript";
script.charset = "UTF-8";
script.onerror = this._scriptError.bind(this);
script.onload = function() {
debug("onload");
self2._abort(new Error("JSONP script loaded abnormally (onload)"));
};
script.onreadystatechange = function() {
debug("onreadystatechange", script.readyState);
if (/loaded|closed/.test(script.readyState)) {
if (script && script.htmlFor && script.onclick) {
self2.loadedOkay = true;
try {
script.onclick();
} catch (x) {
}
}
if (script) {
self2._abort(new Error("JSONP script loaded abnormally (onreadystatechange)"));
}
}
};
if (typeof script.async === "undefined" && global2.document.attachEvent) {
if (!browser.isOpera()) {
try {
script.htmlFor = script.id;
script.event = "onclick";
} catch (x) {
}
script.async = true;
} else {
script2 = this.script2 = global2.document.createElement("script");
script2.text = "try{var a = document.getElementById('" + script.id + "'); if(a)a.onerror();}catch(x){};";
script.async = script2.async = false;
}
}
if (typeof script.async !== "undefined") {
script.async = true;
}
var head = global2.document.getElementsByTagName("head")[0];
head.insertBefore(script, head.firstChild);
if (script2) {
head.insertBefore(script2, head.firstChild);
}
};
module3.exports = JsonpReceiver;
}).call(this);
}).call(this, { env: {} }, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
}, { "../../utils/browser": 44, "../../utils/iframe": 47, "../../utils/random": 50, "../../utils/url": 52, "debug": 55, "events": 3, "inherits": 57 }], 32: [function(require2, module3, exports3) {
(function(process) {
(function() {
"use strict";
var inherits = require2("inherits"), EventEmitter = require2("events").EventEmitter;
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:receiver:xhr");
}
function XhrReceiver(url, AjaxObject) {
debug(url);
EventEmitter.call(this);
var self2 = this;
this.bufferPosition = 0;
this.xo = new AjaxObject("POST", url, null);
this.xo.on("chunk", this._chunkHandler.bind(this));
this.xo.once("finish", function(status, text) {
debug("finish", status, text);
self2._chunkHandler(status, text);
self2.xo = null;
var reason = status === 200 ? "network" : "permanent";
debug("close", reason);
self2.emit("close", null, reason);
self2._cleanup();
});
}
inherits(XhrReceiver, EventEmitter);
XhrReceiver.prototype._chunkHandler = function(status, text) {
debug("_chunkHandler", status);
if (status !== 200 || !text) {
return;
}
for (var idx = -1; ; this.bufferPosition += idx + 1) {
var buf = text.slice(this.bufferPosition);
idx = buf.indexOf("\n");
if (idx === -1) {
break;
}
var msg = buf.slice(0, idx);
if (msg) {
debug("message", msg);
this.emit("message", msg);
}
}
};
XhrReceiver.prototype._cleanup = function() {
debug("_cleanup");
this.removeAllListeners();
};
XhrReceiver.prototype.abort = function() {
debug("abort");
if (this.xo) {
this.xo.close();
debug("close");
this.emit("close", null, "user");
this.xo = null;
}
this._cleanup();
};
module3.exports = XhrReceiver;
}).call(this);
}).call(this, { env: {} });
}, { "debug": 55, "events": 3, "inherits": 57 }], 33: [function(require2, module3, exports3) {
(function(process, global2) {
(function() {
"use strict";
var random = require2("../../utils/random"), urlUtils = require2("../../utils/url");
var debug = function() {
};
if (process.env.NODE_ENV !== "production") {
debug = require2("debug")("sockjs-client:sender:jsonp");
}
var form, area;
function createIframe(id) {
debug("createIframe", id);
try {
return global2.document.createElement('