-
Notifications
You must be signed in to change notification settings - Fork 31
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
Serializing object that has line breaks or other control characters in it #25
Comments
Can you give a concrete example which fails? This seems similar to #20 which got reported upstream as cognitect/transit-js#40 but I was unable to reproduce. I've just added a2bb3b6 to the testsuite which shows that this appears to work fine in a small case. |
It might be related to double-encoding... Like if it is
Though I am not sure. So far I had no time to play with it and find some super simple reproduceable example, but the issue is still there for me (we just do not put any funky stuff into URL anymore ;) ) |
I solved the issue by adding an extra set of slashes:
Picked it up from here: https://magp.ie/2011/01/20/addslashes-and-stripslashes-in-javascript/ |
I still can't seem to find a way to get those characters to appear in the serialised output. If you could provide a small example that does it would be really helpful. |
I guess it is hard to find an example since this only happens when we transfer redux state from server to client this way: import {toJSON} from 'transit-immutable-js';
const Data = ({data}) => (
<script
dangerouslySetInnerHTML={{__html: `window.__data='${toJSON(data)}';`}}
charSet="UTF-8" />
);
const Html = ({app, store}) => (
<html>
<body>
<div id="app" dangerouslySetInnerHTML={{__html: component ? ReactDOM.renderToString(app) : ''}} />
<Data data={store.getState()} />
</body>
</html>
); I've just thought that it might be as well a problem somewhere in React's |
Yes you are exactly right, @glenjamin the example provided by @nkbt sums it up nicely. What simply seems to happen is that the string is stripped of slashes automatically. Consider this: open the console (in a new tab of your browser!) and simply run:
The output will be Now of course it is out of scope for this library to solve this because it has nothing to do with serialization (and it's obviously not limited to serializing immutable.js objects), but on the other hand, I would assume that this is a very common real world example of how people would use transit and transit-immutable-js. So maybe the question is how and where we should present this information and provide examples on how to solve it? |
Ah, ok I see the problem now - it's because the underlying transit lib mostly deals with strings rather than objects (rather annoyingly, see cognitect/transit-js#23). It's not safe to spit a string out onto the page by simply wrapping it in quotes, as you need to deal with escaping. The safest way to get JS to encode a string value as a string you can place on the page is actually to use const Data = ({data}) => (
<script
dangerouslySetInnerHTML={{__html: `window.__data=${JSON.stringify(toJSON(data))};`}}
charSet="UTF-8" />
); We use If we added |
@glenjamin Ok, I think this makes sense, thank you. I will subscribe to the issue you referred to. |
+1 for the |
I see! In this case double-encoding is not critical and it will work for us I will check if it works reliably and let you know
|
Too many quotes there, leave out the single quotes.
|
My fix for the moment, encode JSON safely with base64 (unicode): https://github.com/mathiasbynens/base64 Serverconst Data = ({data}) => (
<script
dangerouslySetInnerHTML={{__html: `window.__data='${base64.encode(toJSON(data))}';`}}
charSet="UTF-8" />
); Client this.store = createReduxStore(fromJSON(base64.decode(window.__data))); Works without issues. |
Hm, yeah, that worked as well. I reckon it is still better then base64 ;) |
Thanks, for now it works with an extra |
Closing in favour of #27 which has a nice short summary. |
Not sure if this is the right place to ask this. I'm building a universal React app and I'm using this module to serialize my immutable Redux store, which is then printed as a javascript variable and picked up by my client code:
Server:
Client:
However, if there are any line breaks or other control characters the browser will complain about "unexpected token in JSON". Do I also have to escape the string before printing it to the browser? All examples I've found of using this library doesn't do this but also doesn't seem to take into account the possibility of line breaks etc. in the JSON content.
The text was updated successfully, but these errors were encountered: