I have a text input box, within a SPA built on AngularJS, for users to add a title to a printout. The input box is declared like this:
<input class="chart-title" type="text" ng-model="chartTitle" ng-change="titleChanged()"/>
The text box is filled with a default title provided by the server. A user may change the title to whatever suits them. When the title is changed, the server is updated and sends back a new title in the header of the response which then replaces the title in the box. This works perfectly for standard ASCII type characters.
However, for unicode characters (for example àßéçøö) it does not work. The text is sent down correctly, updated on the server correctly, and returned to the SPA correctly. The headers for the request/response are here:
Request URL:http://blahblahblah/api/.....&chartTitle=Instrument:%20%C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6
Response Headers:
chartTitle: Instrument: %C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6
The request is made using AngularJS $http(). As you can see the values match up (the space in the request codes out as %20 for obvious reasons). However, when I retrieve the header, using headers("charttitle"), the value I receive is Instrument: à Ãéçøö
The javascript bundle is declared in the index with charset utf-8:
<script src="/js/bundle.js" type="text/javascript" charset="UTF-8"></script>
In addition the html is declared with the correct charset, it seems to me in two places within the head declaration:
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<meta charset="utf-8" />
According to this website (http://www.i18nqa.com/debug/utf8-debug.html) it appears that I am getting Windows1252 character encoding. This does not make any sense. I could, if absolutely necessary, write a horrible hack converting the utf-8 string to Windows1252 characters, but this seems a little extreme and quite error prone to me.
The effect is the same, whether on Chrome, Firefox or IE11. The full request headers are here:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Host:blahblahblah
Origin:http://blahblahblah
Referer:http://blahblahblah/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Is there anything I have left out? Anything that has been forgotten?
EDIT
Full response headers as requested.
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:chartTitle
Cache-Control:private
chartTitle:Instrument: %C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6
Content-Disposition:attachment; filename=PrintData.pdf
Content-Length:1391643
Content-Type:application/octet-stream
Date:Fri, 20 Jan 2017 11:19:07 GMT
Server:Microsoft-IIS/10.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcR2l0XEVPU1xSZXZpZXdlci5XZWJcYXBpXFByaW50XGQyOTNkNjA4NWVlYzlhNTEwYjQ5YThmZGQxNjNhMjAwMWZhYTFjMGY5YzhiMzUxYzE5ZjYxYWMwYTY1OWVhMDM=?=
Code around the headers
$http({
method: 'GET',
url: filePath,
params: {
fileName: fileName
},
responseType: 'arraybuffer',
headers: {'Content-Type' : 'application/json; charset=UTF-8'}
}).success(function (data, status, headers) {
ready();
if (status == 200) {
var chartTitle = headers("charttitle");
var printoutInformation = {'chartTitle' : chartTitle, 'pdfData' : data};
deferred.resolve(printoutInformation);
}
else {
deferred.resolve(null);
}
}).error(function (data) {
ready();
console.log(data);
});
return deferred.promise;
EDIT
The web.config for the api also specifies utf-8:
<globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
TL;DR
In a text box I want to display "Instrument àßéçøö" and instead I am seeing "Instrument: à Ãéçøö"
Here is your issue solved.
Based on this source,
UTF-8 character debugging and its encoding and decoding
The response you are getting is the actual charecter of the encoded utf-8 string
So, you need to decode that inorder to get your result.
HEre is the code to do it.
decoded = decodeURIComponent('%C3%A0%C3%9F%C3%A9%C3%A7%C3%B8%C3%B6')
console.log(decoded);
The result is => "àßéçøö"
we have to do this to get the actual string instead of UTF-8
So, from your response you got,à Ãéçøö
decodeURIComponent(escape("à Ãéçøö")) => "àßéçøö"
DEFINITION:
decodeURIComponent():
A new string representing the decoded version of the given encoded Uniform Resource Identifier (URI) component.
So , here is your method.
if (status == 200) {
var original = headers("charttitle");
var chartTitle = decodeURIComponent(escape(original));
console.log(chartTitle);
var printoutInformation = {'chartTitle' : chartTitle, 'pdfData' : data};
deferred.resolve(printoutInformation);
}
Now, you will get the headers same as you send.
Try below for encoding
myAngApp1=document.getElementById("ItemSearch");
var uri = myAngApp1.value;
var place = encodeURIComponent(uri)
Related
In my HTML file, I have a single line (below) that gets a response from a device over WiFi & makes data available to my JavaScript, it works well except when there is an error in the response text & it halts.
<script type="text/javascript" src="http://192.168.4.1/"></script>
The response is a text string representing JavaScript variables, it sometimes gets corrupted throwing an error.
Examples:
Uncaught SyntaxError: invalid assignment left-hand side 192.168.4.1:14:3
SyntaxError: unterminated string literal 192.168.4.1:3:8
I need a solution to capture the error of parsing the received string so I can run the above statement again to get a new string.
Thanks
below is a picture of the response string (JS variables.)
The issue is that once the script is loaded, its content might be misformed and I would like to avoid having errors due to that.
Update #1. get the data with XMLHttpRequest
<script>
const Http = new XMLHttpRequest();
const url='http://192.168.4.1/';
Http.open("GET", url);
// Http.setRequestHeader('Access-Control-Allow-Origin', '*');
Http.send();
ReturnVar = Http.responseText
Http.onreadystatechange = (e) => { console.log(Http.responseText) }
</script>
Below is the detail in browser Console, Headers after script above run.
GET
scheme http
host 192.168.4.1
filename /
Address 192.168.4.1:80
Transferred 1.82 KB (1.82 KB size
Request headers (278B)
GET /
Host: 192.168.4.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
DNT: 1
Connection: keep-alive
Cache-Control: max-age=0
You have a script tag, which is loading the script and evaluating its content. You need to programmatically modify this, so you need to
Get the file as a text
https://www.freecodecamp.org/news/here-is-the-most-popular-ways-to-make-an-http-request-in-javascript-954ce8c95aaa/
You just need to programmatically download the content the file, not as the src of a script.
Evaluate it
Before you proceed, read this: https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
Now, that you know that eval is not exactly popular - and rightly so - and if you are still sure you need to run a script as it is, study eval and make it work equivalently as it was
Encapsulate it into try-catch
Example for error:
eval("'");
Example for error in try-catch:
try {eval("'")} catch (ex) {}
you can call the address using ajax, and then if the response is in json you can easily use it, but if its some sort of script or something else, wrap it in a script tag an append it to the body.
assume the result is what you got from ajax request and you have jQuery in your project:
$('body').append('<script>'+result+'</script>')
in this case you can wrap your code in try catch and handle the errors
Trying to make a call and retrieve a very simple, one line, JSON file.
$(document).ready(function() {
jQuery.ajax({
type: 'GET',
url: 'http://wncrunners.com/admin/colors.json' ,
dataType: 'jsonp',
success: function(data) {
alert('success');
}
});
});//end document.ready
Here's the RAW Request:
GET http://wncrunners.com/admin/colors.json?callback=jQuery16406345664265099913_1319854793396&_=1319854793399 HTTP/1.1
Host: wncrunners.com
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2
Accept: */*
Referer: http://localhost:8888/jquery/Test.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Here's the RAW Response:
HTTP/1.1 200 OK
Date: Sat, 29 Oct 2011 02:21:24 GMT
Server: Apache/1.3.33 (Unix) mod_ssl/2.8.22 OpenSSL/0.9.7d SE/0.5.3
Last-Modified: Fri, 28 Oct 2011 17:48:47 GMT
ETag: "166a2402-10-4eaaeaff"
Accept-Ranges: bytes
Content-Length: 16
Content-Type: text/plain
Connection: close
{"red" : "#f00"}
The JSON is coming back in the response (red : #f00), but Chrome reports Uncaught SyntaxError: Unexpected token : colors.json:1
If I navigate directly to url itself, the JSON is returned and is displayed in the browser.
If I paste the contents of colors.json into JSLINT, the json validates.
Any ideas why I can't get this error and I never make it to the success callback?
EDIT - the jQuery.ajax() call above runs perfect at jsfiddle.net, and returns the alert 'success' as expected.
EDIT 2 - this URL works fine 'http://api.wunderground.com/api/8ac447ee36aa2505/geolookup/conditions/q/IA/Cedar_Rapids.json' I noticed that it returned as TYPE: text/javascript and Chrome did not throw the Unexpected Token. I've tested several other url's and the ONLY one that does not throw the Unexptected Token is the wunderground that is returned as TYPE: text/javascript.
Streams returned as text/plain and application/json are not being parsed correctly.
You've told jQuery to expect a JSONP response, which is why jQuery has added the callback=jQuery16406345664265099913_1319854793396&_=1319854793399 part to the URL (you can see this in your dump of the request).
What you're returning is JSON, not JSONP. Your response looks like
{"red" : "#f00"}
and jQuery is expecting something like this:
jQuery16406345664265099913_1319854793396({"red" : "#f00"})
If you actually need to use JSONP to get around the same origin policy, then the server serving colors.json needs to be able to actually return a JSONP response.
If the same origin policy isn't an issue for your application, then you just need to fix the dataType in your jQuery.ajax call to be json instead of jsonp.
I have spent the last few days trying to figure this out myself. Using the old json dataType gives you cross origin problems, while setting the dataType to jsonp makes the data "unreadable" as explained above. So there are apparently two ways out, the first hasn't worked for me but seems like a potential solution and that I might be doing something wrong. This is explained here [ https://learn.jquery.com/ajax/working-with-jsonp/ ].
The one that worked for me is as follows:
1- download the ajax cross origin plug in [ http://www.ajax-cross-origin.com/ ].
2- add a script link to it just below the normal jQuery link.
3- add the line "crossOrigin: true," to your ajax function.
Good to go! here is my working code for this:
$.ajax({
crossOrigin: true,
url : "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.86,151.195&radius=5000&type=ATM&keyword=ATM&key=MyKey",
type : "GET",
success:function(data){
console.log(data);
}
})
I had the same problem and the solution was to encapsulate the json inside this function
jsonp(
.... your json ...
)
That hex might need to be wrapped in quotes and made into a string. Javascript might not like the # character
I'm trying to get JSON string from an URL:
http://megarkarsa.com/gpsjson.php
The URL echoes JSON location value to be shown as string, with this result for example:
{"BMS":[{"id":"PR01","type":"prajurit","lat":"-6.253310","long":"107.156219"},{"id":"PR02","type":"prajurit","lat":"-6.224084","long":"106.653069"},{"id":"PR03","type":"kendaraan","lat":"-6.244316","long":"106.649734"}]}
I need to get this string from javascript, so i can parse it later with JSON.parse(string).
I have tried to use getJson, but seems it can't be done since it's not real Json value, but string.
How can i do that? Every suggestion will be appreciated.
Why not just jQuery ?
$.get('http://megarkarsa.com/gpsjson.php',function(data){
console.log(data);
},'json');
or use php :
<?php
$json=file_get_contents('http://megarkarsa.com/gpsjson.php');
$json=json_decode($json,true);
?>
if you already did all and still not working, try :
$.get('http://megarkarsa.com/gpsjson.php',function(data){
data = eval ("(" + data + ")");
console.log(data);
});
The last solution is dangerous, use it if you trust the API you working with
As Michael Antonio pointed out, using Ajax would be the way to do it. Heres my code
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON</title>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(function() {
$.ajax({
url: 'http://megarkarsa.com/gpsjson.php',
type: 'GET',
dataType: 'html',
success: function(data, status, xhr)
{
$("#json").html(data);
},
error: function(xhr, status, error)
{
$("#json").html("Error: " + status + " " + error);
}
});
});
</script>
</head>
<body>
<div id="json"></div>
</body>
</html>
However, an error keeps cropping up. Here are the request/response headers, notice the response is force closing the connection.
Request
Host: megarkarsa.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://testsites.kalebklein.com/json1/json.html
Origin: http://testsites.kalebklein.com
Connection: keep-alive
Response
Connection: close
Content-Type: text/html
Date: Mon, 21 Sep 2015 01:52:56 GMT
Server: Apache
Transfer-Encoding: chunked
x-powered-by: PHP/5.4.36
Also notice that the content-type of the response is HTML, and should be JSON if you wish to parse the JSON using the above Ajax function I provided. The error coming back is not helpful whatsoever, meaning that the connection is being cut off or refused by making the Ajax call, and no data is being sent back.
You can do this as well :
str='{"BMS":[{"id":"PR01","type":"prajurit","lat":"-6.253310","long":"107.156219"},{"id":"PR02","type":"prajurit","lat":"-6.224084","long":"106.653069"},{"id":"PR03","type":"kendaraan","lat":"-6.244316","long":"106.649734"}]}'; //example string
obj=jQuery.parseJSON( (str)); //parse as json
$.each(obj, function (i, item) { //loop through each item in main obj
$.each(item, function (i, y) { loop through each prop in item
alert(y.id) //you can access the values like this others can be accessed via the dot notation such as y. prajurit
});
});
We are developing a mobile site using html5, jQuery(1.8.2) and jQuery mobile while making jQuery ajax calls (get and post).
After we changed our domain name, we are getting "access denied" for ajax calls on ie9.
We tried to include jquery.iecors.js. But still we are getting the same error.Is there any resolution for this?
Sample Code:
$.support.cors = true;
$.ajax({
cache: false,
async: true,
crossDomain: true,
timeout: 600000,
url: baseUrl + '/SmartTouch/restServices/PrefferedHotels',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + myencoded);
},
contentType: "application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8",
success: function (data) {
alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
alert("error!!::" + JSON.stringify(jqXHR));
alert('response: ' + jqXHR.responseText);
alert('code: ' + jqXHR.getResponseHeader('X-Subscriber-Status'));
alert("textStatus " + textStatus);
alert("errorThrown " + errorThrown);
}
});
Edited:
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + myencoded);
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
},
contentType: "application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8",
success: function (data) {
alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
alert("error!!::" + JSON.stringify(jqXHR));
Request and Response headers in IE9:
Request:
Key Value
Request GET url HTTP/1.1
Accept text/html, application/xhtml+xml, */*
Accept-Language en-US
User-Agent Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Accept-Encoding gzip, deflate
Proxy-Connection Keep-Alive
Host ("url")
Pragma no-cache
Cookie GUEST_LANGUAGE_ID=en_US; COOKIE_SUPPORT=true; __utmc=24444716; __utma=24444716.47018335.1379597653.1380274476.1380276859.17; __utmz=24444716.1379597653.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=24444716.6.10.1380276859
Response:
Key Value
Response HTTP/1.1 200 OK
Server Apache-Coyote/1.1
X-Powered-By Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Accept-Ranges bytes
ETag W/"64578-1380266616000"
Last-Modified Fri, 27 Sep 2013 07:23:36 GMT
Content-Type text/html
Date Fri, 27 Sep 2013 10:17:01 GMT
Content-Length 64578
Age 0
Via 1.1 localhost.localdomain
This kind of Content-Type looks strange:
application/x-www.form-urlencoded; (http://www.form-urlencoded;) (http://www.form-urlencoded;) charset=UTF-8"
I can imagine the IE has as problem with it.
Try the proper one:
application/x-www-form-urlencoded; charset=UTF-8
^-- notice: no dot!
It's also possible for the IE to have problems with the authorization.
Maybe myencoded is out of the scope or not filled correctly. Debug this variable and have a look at this question: Authorization through setRequestHeader
If you want the Ajax url to be hit from any domain, the server must send a response header Access-Control-Allow-Origin : * or Access-Control-Allow-Origin : your-domain if restricted only to your domain.Can you see these headers in response?
See this Microsoft article on CORS implementation on IE8 and IE9: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Specifically they say two things:
No custom headers may be added to the request
and
No authentication or cookies will be sent with the request
And you mentioned in your comment:
Our problem is we are doing basic authorization and including following header: xhr.setRequestHeader("Authorization", "Basic " + myencoded); in our ajax call.But in ie9 we are getting access denied.Is there any way to include this header?
Unfortunately, the answer I'll have to give you is no, there is no way to include this header in IE8 or IE9. Microsoft designed it that way.
To get it to work with CORS on IE9 you'll have to convince the site you're connecting to to allow you to send authorization information some other way - maybe query params or post data.
If the site is not cooperative there's always the request proxy work-around where you request to a page on your server and you server forwards the request with the correct header etc.
You seem confident that the issue has nothing to do with the suggested jQuery bug (especially since you're using jquery.iecors.js) so I'll move right on.
What is the significance of the "edited" bit? Access-Control-Allow-Origin:* should be set on the response (i.e. server-side, as part of Apache/IIS/F5 configuration), not on the request. Edit: there is more information available on MDN; you could also use something like burp's tampering proxy to play with the headers if you don't have immediate access to config changes (pretty common in an enterprise environment)
Even if not an issue, #DanFromGermany is absolutely right - content-type does look strange. You shouldn't even have to set it manually, jQuery.ajax() has it correct by default.
You also seem concerned with setting the basic authentication header. Remember that myencoded value is just encoded (not encrypted), so you might as well skip the header and pass credentials in the URL: http(s)://username:password#www.example.com/
Moar edit:
Looking through those MDN docos above, this seems relevant:
By default, in cross-site XMLHttpRequest invocations, browsers will
not send credentials. A specific flag has to be set on the
XMLHttpRequest object when it is invoked.
Perhaps try adding xhr.withCredentials = true; to your beforeSend?
Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example
would fail if the header was wildcarded as:
Access-Control-Allow-Origin: *. Since the Access-Control-Allow-Origin
explicitly mentions http://foo.example, the credential-cognizant
content is returned to the invoking web content.
This would invalidate previous advice of using an asterisk in the header (i.e. explicit domain is required)
If you were using windows based hosting?
Please check old configs for the IIS, if available,
there are security provisions which will allow content by its type,
add this response header <% Response.AddHeader("Access-Control-Allow-Origin","*") %> in your page also.
or refer the source link to MSDN for more details
I think you have updated this in edits but there are many things as its AJAX involved, and your IE9 may also one of the reason if you have changed security options and not default.
I think that should do, if not please reply
You can try this
<meta http-equiv="X-UA-Compatible" content="IE=Edge" >
It forces the browser the render at whatever the most recent version's standards are. For reference http://msdn.microsoft.com/en-us/library/ie/ms533876%28v=vs.85%29.aspx
I am trying to build Multipart Form Data directly in Javascript in order to send my data to a server. I know there are Ajax form plugins, but I really think they wont suit my needs as I will create binary data in the browser and send it as if it were a file submit (The server I will post to requires it that way).
My problem now is that the simplest example of building text Multipart MIME data fails on the server side with an error:
500 Internal Server Error: Invalid boundary in multipart form
I have tried to reduce the code to a bare minimum: In this main.html (this is the name it will be refered to later in the server code) , there are both an html form to submit text the html-non-Ajax way and also a Javascript function which tries to replicate that with XmlHttprequest:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Posting MIME Multipart directly in Javascript</title>
<script>
function sendMimeMultipart(url, data) {
boundary = '---------------------------1504702169761927311267328916'
xhr = new XMLHttpRequest();
xhr.open("POST", url);
//Build the MIME POST request.
var body = "--" + boundary + "\r\n";
body += 'Content-Disposition: form-data; name="contents"\r\n\r\n';
body += data+"\r\n";
body += "--" + boundary + "--"+"\r\n";
var fileSize = body.length
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
xhr.setRequestHeader("Content-Length", fileSize);
xhr.send(body);
return true;
}
function sendData() {
sendMimeMultipart('http://localhost:8080/myhandler', "Hello World!");
}
</script>
</head>
<body onload='sendData()'>
<form action = "myhandler" method = "post" enctype = "multipart/form-data">
<input type = "text" name = "contents">
<input type = "submit">
</form>
</body>
</html>
This is the Request object that arrives to the server when using the form:
Request: POST /myhandler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Connection: keep-alive
Content-Length: 187
Content-Type: multipart/form-data;
boundary=---------------------------18171295601131570933197493099
Host: localhost:8080
Keep-Alive: 115
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20)
Gecko/20110803 Firefox/3.6.20
-----------------------------18171295601131570933197493099
Content-Disposition: form-data; name="contents"
Hello World!
-----------------------------18171295601131570933197493099--
And this the Request object arriving to the server when using the Javascript function (sendMimeMultipart):
Request: POST /myhandler
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 185
Content-Type: multipart/form-data; charset=UTF-8,
boundary=---------------------------1504702169761927311267328916
Host: localhost:8080
Keep-Alive: 115
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20)
Gecko/20110803 Firefox/3.6.20
-----------------------------1504702169761927311267328916
Content-Disposition: form-data; name="contents"
Hello World!
-----------------------------1504702169761927311267328916--
The difference of 2 bytes in Content-Length is because the browser generates the boundaries randomly, being sometimes longer and sometimes shorter. In this case it is one character longer, what accounts for the two byte difference in the two boundary occurrences.
I dont think the server has much to do with this, bus just in case I post the server side code. It is an Appengine snippet intended only for localhost usage; the call to "localhost:8080/myhandler" retrieves the value of "contents" posted by the browser and stores it in a global variable. After that, a call to "localhost:8080/show" displays the text previously retrieved. As I mentioned before, if we send the data using the form, the text content is correctly saved and the "show" handler displays it. If however we use the Javascript, the line of code:
contents = self.request.get("contents")
In MyHandler (code below), produces the error.
Here is the server code:
import cgi
import datetime
import logging
import os
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
from google.appengine.ext.webapp import template
from os import environ
contents=''
class mein(webapp.RequestHandler):
def get(self):
template_values = {}
path = os.path.join(os.path.dirname(__file__), 'templates/main.html')
self.response.out.write(template.render(path, template_values))
class MyHandler(webapp.RequestHandler):
def post(self):
global contents
contents = self.request.get("contents")
class Show(webapp.RequestHandler):
def get(self):
global contents
self.response.headers['Content-Type'] = "text/plain"
self.response.out.write(contents)
application = webapp.WSGIApplication([
('/', mein),
('/myhandler', MyHandler),
('/show', Show)
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
Any idea of why this should be failing? I have tried a zillion different things, but I dont seem to be able to make it work or to understand the reason why it doesnt!.
Thanks very much in advance for your ideas and help.
All the best:
-Javier
I encountered the same error message when trying to construct a http file upload manually. I got it to work by replacing the comma(,) with a semicolon(;) in the Content-Type headers. In your case, by replacing:
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
with:
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary="+boundary);
This seems to be related to the Python backend, because I had this same problem with Django(Python) and when I debugged it against a PHP test server both comma and semicolon worked.
Finally, the example in RFC1867 DO use a comma so in the end I'm unsure what really is the correct way to do it, but semicolon solved it for me.