I'm trying to encode an object in a Python script and set it as a cookie so I can read it with client-side JavaScript.
I've run into problems every way I've tried to do this. Generally, the cookie is formatted in a way that makes JSON.parse() break.
My current script:
cookie = Cookie.SimpleCookie()
data = {"name": "Janet", "if_nasty": "Ms. Jackson"}
cookie['test'] = json.dumps(data)
self.response.headers.add_header("Set-Cookie", cookie.output(header=''))
... which results in
test="{\"name\": \"janet\"\054 \"if_nasty\": \"Ms. Jackson\"}"
on the client.
I don't really want to introduce a hack-y solution to replace instances of commas when they appear. Any ideas how I can pass complex data structures (both by setting and reading cookies) with Python?
I also wanted to read a cookie (that had been set on the server) on the client. I worked around the issue by base64 encoding the JSON String, however there are a few small gotchas involved with this approach as well.
1: Base64 strings end with 0-2 equal signs, and these were being converted into the string \075. My approach is to revert those characters into equal characters on the client.
2: The base64 string is being enclosed in double quote characters in the cookie. I remove these on the client.
Server:
nav_json = json.dumps(nav_data)
nav_b64=base64.b64encode(nav_json)
self.response.set_cookie('nav_data', nav_b64)
Client:
var user_data_base64= $.cookie('nav_data');
// remove quotes from around the string
user_data_base64 = user_data_base64.replace(/"/g,"");
// replace \075 with =
user_data_base64 = user_data_base64.replace(/\\075/g,"=");
var user_data_encoded=$.base64.decode( user_data_base64 );
var user_data = $.parseJSON(user_data_encoded);
I am using 2 jquery plugins here:
https://github.com/carlo/jquery-base64
and
https://github.com/carhartl/jquery-cookie
Note: I consider this a hack: It would be better to re-implement the python code that encodes the cookie in javascript, however this also has the downside that you would need to notice and port and changes to that code.
I have now moved to a solution where I use a small html file to set the cookie on the client side and then redirect to the actual page requested. Here is a snippet from the JINJA2 template that I am using:
<script type="text/javascript">
var nav_data='{% autoescape false %}{{nav_data}}{% endautoescape %}';
$.cookie('nav_data', nav_data, { path: '/' });
window.location.replace("{{next}}")
</script>
Note 2: Cookies are not ideal for my use case and I will probably move on to Session or Local Storage to reduce network overhead (although my nav_data is quite small - a dozen characters or so.)
On the Python side:
json.dumps the string
escape spaces - just call .replace(' ', '%20')
Call urllib.parse.quote_plus() then write the string to the cookie
On the JavaScript side:
read the cookie
pass it through decodeURIComponent()
JSON.parse it
This seems to be the cleanest way I've found.
not sure a cookie is the best way of doing this? see the getting started guide for info rendering data to the client
Related
I have a problem which is due to to IIS turning off + as spaces in querystrings.
We have clients posting some data to a hidden page as a querystring (jobs) and they sometimes post jobs with things like C++ in them etc - as they are passing the data we cannot expect them to encode it properly %2B as they are mostly non techie and sometimes they mix n match which is fun.
We also have places where we have querystrings within querystrings (sometimes up to 4 when passing filenames into a flash file for the click link, then the redirect url onclick that goes to a page that logs the click then the final url to go to show the customer!).
There are also other places where we have URLs in URLS such as redirect on login and so on.
Plus signs shouldn't really be a problem but we have found a few issues where they are so I just want one function that can sort it out.
For times when we have needed to encode ASP URLS (due to their being no Server.URLDecode function) even though we mostly don't need to as the page un-encodes them, we use a server side JavaScript ASP Classic (I know!) function e.g
<script language="JavaScript" RUNAT="SERVER">
function URLDecode(strIN)
{
// JS will return undefined for vars that have not been set yet whereas VB doesn't so handle
if(strIN){
var strOUT = decodeURIComponent(strIN);
return strOUT;
}else{ //for undefined or nulls or empty strings just return an empty string
return "";
}
}
</script>
However I am trying to get round any possible problems with + signs with a simple hack where I replace it first with a placeholder then replace it back after decoding e.g
<script language="JavaScript" RUNAT="SERVER">
function URLDecode(strIN)
{
// JS will return undefined for vars that have not been set yet whereas VB doesn't so handle
if(strIN){
strIN = strIN.replace("+","##PLUS##");
var strOUT = decodeURIComponent(strIN);
strOUT = strOUT.replace("##PLUS##","+")
return strOUT;
}else{ //for undefined or nulls or empty strings just return an empty string
return "";
}
}
</script>
However on running this I am getting the following error
Microsoft JScript runtime error '800a01b6'
Object doesn't support this property or method
/jobboard/scripts/VBS/EncodeFuncLib.asp, line 781
this line is
strIN = strIN.replace("+","##PLUS##");
I've tried
strIN = strIN.replace(/\+/g,"##PLUS##");
strIN = strIN.replace('/\+/','##PLUS##');
But nothing seems to work.
Running this code as client side JavaScript works fine so I don't know why it's not running server side.
I don't want to have to search 300+ files for places where this function is called server side and do the placeholder/replace around the URLDecode function so I would like to know what the problems is and how to solve it.is.
At first I thought it was because we had moved to Windows 2012 and IIS 8 and they had a new JS.dll that needed to be install (from reading up on it) - however we still have some 2003 servers on IIS 7 and I am getting the same problem there as well.
Unless my server guy isn't telling me something like the version of IIS we are using on 2003 I don't know what is going on.
Can anybody shed some light on this.
Am I being a numpty?
What could be the issue?
Thanks in advance for any help.
The regex to replace plus signs is strIN = strIN.replace(/\+/g,"##PLUS##"); Because + has a meaning in regex, it needs to be escaped with a backslash.
Does anybody know a way to convert a C# string to a JavaScript String in Asp.net. My code looks like this:
<script>
#{string thing = "Cats";}
var thing = String(#thing);
</script>
</div>
<body onload="eventAlert(thing)"></body>
You need to JavaScript Encode your string before you write it out, otherwise your string may contain characters that cause the JavaScript string constant to be terminated prematurely. You can do this with HttpUtility.JavaScriptStringEncode in the System.Web namespace. Once you have done that you need to stop razor from HTML Encoding the result which can be done with HtmlHelper.Raw like this:
#{string thing = "Cats Special Chars \"!'£$%^&*()#;:";}
var thing = "#Html.Raw(HttpUtility.JavaScriptStringEncode(thing))";
Try the following:
var thing = "#(thing)";
There are a couple of good ways to do this. But a very clean way is to use a cookie. This is clean because you are not injecting javascript code from the server into your static client code. Writing C# to create JavaScript and then insert that into a variable may have timing issues, depending on when your code runs and what .Net is doing. Be very careful in reading strings back for security concerns.
I have two cases here:
My database contains a lot of information which I want to fetch to the page. Some of this information is name which contain non-ASCII characters like Uwe Rülke
- Old solution which works well:
I fetch the data from the database and populate the page directly from a VB while loop. In this case all the chars are displaying correctly Uwe Rülke.
- New solution which doesn't work properly:
The VB While loop doesn't throw the data directly to the page, rather in a JavaScript strings (to enhance performance by not calling the database each now and then). But when I used the information stored in the JavaScript variables, I got something like this: Uwe R�lke.
In both cases, the page's encoding is:
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
Where did I go wrong?
This is the code used to fetch (from the database) and then save to JavaScript strings.
I'm using AJAX LOAD from a page called ISEquery to build a specific request and query it from the database. It is used to either fetch data as an Excel file or as plain HTML. At this point the characters are well represented.
Then the magic happens, and the characters get mis-represented. I checked it in the exctractFields function:
$("<div></div>").load("ISEquery.asp?isExcel=0&" + info, function(){
// Extracting the fields into an array
var rows = "";
var options = "";
$(this).children().each(function(index){
var fieldsArray = exctractFields($(this).html());
rows += createISELine(fieldsArray);
options += createISELine_ComboBox(fieldsArray);
});
});
The � means that you used a character which can't be represented properly.
Somewhere between the server and the client, you need to encode the string data properly. I don't know how you transfer the data from the server to the client (generate JavaScript, Ajax, and GET requests). It's hard to say how to fix this.
But what you need to do: For every step, you must make sure that you know what the current encoding of the data is and what the recipient expects.
For example, if you generate inline JavaScript code in an HTML page, then the string value must be encoded with the same encoding as the page (iso-8859-1). If you use Ajax, then usually you have to use UTF-8.
I followed the string from server to the page and found that it is gets misrepresented after the AJAX LOAD, so I found this answer which resolved my problem. Although I had to use the charset="iso-8859-1" for it to work rather than charset="UTF-8".
So the final answer is:
-Encoding in the HTML page:
<meta http-equiv="Content-Type" content="text/html"; charset="iso-8859-1">
-Encoding the Ajax data:
$.ajaxSetup({
'beforeSend' : function(xhr) {
xhr.overrideMimeType('text/html; charset=iso-8859-1');
},
});
And now characters are displayed correctly.
(The lead was from Aaron Digulla's answer.)
The JavaScript default encoding for strings is UTF-16 (16 bits) while ISO 8859-1 is 8 bits.
What is the default JavaScript character encoding?
I think you can use encodeURI() to convert your special characters to ASCII characters and afterwards you can decode it with decodeURI():
JavaScript encodeURI() Function (W3Schools)
I have the following jquery:
var msg = $("#newmessage").val();
var user = $("#userchat").val();
var filename = "/inc/chat.php?msg="+msg+"&user="+user;
alert(filename);
$("#chatData").load(filename);
when 'msg' does not have a space in it, the #chatData loads fine and posts the variable.
When it does have a space in it, I just get a blank div. With no information in it whatsoever.
if I load up the php file that inserts the data into the DB, and manually type the same GET data, it works fine.
Whats going on?
Try using
encodeURIComponent(msg)
Also consider:
$("#chatData").load('/inc/chat.php',
{ 'msg' : $("#newmessage").val(), 'user' : $("#userchat").val() }
);
URI encoding is done, if needed, by jQuery.
You don't have to worry about URI encoding as the POST method is used since data is provided as an object (source).
In this case POST may be better than GET anyways.
If you were using $_GET in your php file you will need to use either $_REQUEST or $_POST.
you have to encode your message before sending using encodeURIComponent() and decode on server-site using urldecode().
doing this will escape/encode special characters that aren't allowed in an url or that will break your query-string otherwise (like a & in your message that would otherwise start a new argument).
You can use either escape, encodeURI or encodeURIComponent, but escape is the only method supported by every browser, although most modern browsers support the latter.
Reference
Take a look at this document, which does a good job of explaining all three.
The space could be causing an issue - try javascript's encodeURIComponent():
var msg = encodeURIComponent($("#newmessage").val());
var user = encodeURIComponent($("#userchat").val());
I have moss service which output the url of image.
Lets say the output url has '&' character , the service appending amp; next to &.
for ex: Directory.aspx?&z=BWxNK
Here amp; is additionally added. it is a moss sevice. so i don't have control on the sevice.
what i can do is decode the output. As i am using Ajax calls for calling moss sevice i am forced to decode the out put from javascript. i tried decodeURIComponent,decodeURI,unescape. nothing solved the problem.
Any help greatly appreciated. even server side function also helpful. i am using Aspl.net MVC3
Regards,
Kumar.
& is not URI encoded, it's HTML encoded.
For a server side solution, you could do this:
Server.HtmlDecode("&") // yields "&"
For a JavaScript solution, you could set the html to "&" and read out the text, to simulate HTML decoding. In jQuery, it could look like this:
$("<span/>").html("&").text(); // yields "&"
& is SGML/XML/HTML for &.
If the service is outputting an XML document, then make sure you are using an XML parser to parse it (and not regular expressions or something equally crazy).
Otherwise, you need decode the (presumably) HTML. In JavaScript, the easiest way to do that is:
var foo = document.createElement('div');
foo.innerHTML = myString;
var url = foo.firstChild.data;