-
Notifications
You must be signed in to change notification settings - Fork 569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The cache busting t query parameter does not work if multiple connections to the server are made #690
Comments
Hi! That's an... interesting behavior, thanks for the detailed analysis. Do you have a suggestion for how to fix this? |
I can't confidently suggest a fix without a deeper understanding of why engine.io uses yeast, which creates the Here's my understanding: Here's the yeast implementation: My take is that this is not ideal. yeast will generate guaranteed unique values within a single js context, but not within multiple js contexts like my issue, multiple iframes loading all at once and timestamp lucking into the same I'd replace yeast altogether with something like: // yeast-replacement.ts
// guarantee unique within a single js context, like yeast
let suffixUnique = 0;
// probably unique within multiple js contexts
const jsUnique = Math.random().toString(36).replace('.', '');
export function generateId() {
// time based cache bust, like yeast
const timeUnique = Date.now().toString(36);
return timeUnique + jsUnique + (suffixUnique++).toString();
} Or continue using yeast, and append a one time created jsUnique to every yeast generated id. That's probably the best approach. |
The yeast() method could generate the same string twice when used in two different iframes, which can cause Safari to only send one HTTP request (deduplication) and trigger an HTTP 400 error afterwards since the two iframes share the same session ID. This new method, combining 5 chars from the timestamp and 3 chars from Math.random() should be sufficient for our use case. Related: socketio/engine.io#690 See also: 874484c
The format of the query parameter has been updated: socketio/engine.io-client@b624c50 (included in version 6.6.0). It now uses: export function randomString() {
return (
Date.now().toString(36).substring(3) +
Math.random().toString(36).substring(2, 5)
);
} Thanks! |
This bug seems unique to Safari deduplicating identical concurrent network requests across embedded iframes.
The
t
query parameter is a timestamp that is intended for use with cache busting. This cache busting does not work if multiple iframe connections are made to the same server within the same page at the same time. I think this issue is specifically limited to limited toyeast
generation in iframes, in Safari.My use case creates a connection per iframe (for example, lets say 4). These 4 iframes all load at the same time and
t
value is the same for each iframe. Safari uses the same network executor for each iframe within the main page. Since the same request is for each iframe (including thet
value), Safari decides to execute the request once and return the samesid
response to all 4 frames. This causes three of the engine io connections to fail with a 400 error on subsequent xhr.I am adding my own cache busting query parameter to fix this (as well as confirm the underlying pseudorandom seed issue in iframes).
Expected behavior
The cache busting parameter
t
should be actually random and not a time based deterministic value, since that fails in iframe scenarios.Platform:
The text was updated successfully, but these errors were encountered: