I'm trying to get an Xmlhttp.response from a website, specifically with this part of code:
var apiUrl = "http://somesite/someapicall/correctapiKey";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", apiUrl, false);
xmlHttp.setRequestHeader("Content-Type", "application/json");
var data {
"username": username,
"password": hashedPass,
"someOption": "true",
"someOtherOption": "true"
}
xmlHttp.send(data);
var response = xmlHttp.responseText;
var parsed = eval('(' + response + ')');
If i put in the actual strings in "username": & "password" instead of using the variables the code does work. with the variables it fails.
I'm probably missing something small again, but i really can't see it and i'm breaking my head over it since this afternoon :(
anyone ? please...
edited: the username and the hashed pass are given as variables with known correct values. changed the code to reflect the use of the variables
This:
var apiUrl = "http://somesite/someapicall/correctapiKey";
uses an absolute URI, which implies you may be performing a cross-origin request. Make sure you aren't going to run into problems with the Same Origin Policy. (See also ways to circumvent it).
This:
var data {
"username": username,
"password": hashedPass,
"someOption": "true",
"someOtherOption": "true"
}
… is a syntax error. You need an = sign after data.
If the last two options are supposed to be booleans, they shouldn't have quotes around them.
You should avoid automatic semi-colon insertion. Put a ; after the }.
This:
xmlHttp.send(data);
… will convert data to a string by calling toString() on it. This will give you [Object object].
If you want to send JSON, then you must convert the JavaScript object to JSON:
data = JSON.stringify(data);
This:
var parsed = eval('(' + response + ')');
is evil, slow, hard to debug and potentially dangerous if you get an expected response. Use a JSON parser instead:
var parsed = JSON.parse(response);
Related
I have the following html code and it works as intended when I hard code my dateTime. However I am trying to pass a selected value from datePicker into my ct variable. The host application will only process ISOdates so am trying to convert on the client side. Where am I going wrong? thanks in advance.
<script type="text/javascript" language="javascript">
function send()
{
var setParam1 = document.getElementById("fparam1").value;
var setParam2 = document.getElementById("fparam2").value;
var setDate = document.getElementById("dateid").value;
var ct=new Date(setDate).toISOString();
var ItemJSON;
ItemJSON = '{"c8y_rlim":{"ul":{"value":'+setParam1+',"unit":"na"}},"time":'+ct+',"source": {"id":"681700"},"type":"c8y_ph"}';
URL = "/measurement/measurements/" ; //Your URL
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
xmlhttp.open("POST", URL, false);
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.setRequestHeader("Accept", "application/json");
xmlhttp.setRequestHeader('Authorization', 'Basic ' + window.btoa('user:pw'));
xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
xmlhttp.send(ItemJSON);
alert(xmlhttp.responseText);
}
function callbackFunction(xmlhttp)
{
//alert(xmlhttp.responseXML);
}
</script>
<html>
<p><label for="DateID">DateTime:</label><br>
<input type="datetime-local" name="Date" id="dateid"><br>
<label for="fparam1">Param 1:</label><br>
<input type="number" id="fparam1" name="fparam1"><br>
<label for="fparam2">Param 2:</label><br>
<input type="number" id="fparam2" name="fparam2"><br>
</p><br><button type="submit" onclick="javascript:send()">Submit</button>
</html>
It looks like you're properly setting the ct variable to an ISOString.
I believe your problem is with the manual JSON stringification you're doing.
In short, here's a link to a fiddle that should do what you want.
To expand, javascript has built in JSON functionality for converting javascript object to json and vice-versa. So instead of manually concatenating your variables into a json string, you should create an object and then stringify it!
var setDate = document.getElementById("dateid").value;
var ct = new Date(setDate).toISOString();
var ItemObject = {
c8y_rlim: {
ul: {
value: setParam1,
unit: "na",
},
},
time: ct,
source: {
id: 681700,
},
type: "c8y_ph",
};
var ItemJSON = JSON.stringify(ItemObject);
// ItemJSON is now a JSON string!
Some notes on this:
It would be wise to wrap your JSON stringification code in a try/catch block, as it will throw an error if it can't properly serialize your object.
Per W3C: type="datetime-local" is not supported in Firefox, Safari or Internet Explorer 12 (or earlier).
At number 1 on OWASP's top 10 web app security risks is injection. Be wary of accepting raw input data without any sort of validation, especially when you're sending it off somewhere.
Hope this helps!
I would advise against writing your own JSON string directly, as it greatly increases the chance of a syntax error.
In this case, you are doing:
/.../ "time":'+ct+' /.../
Which is the likely culprit behind breaking the JSON parsing on the server. The ISO datetime string is a string, and should thus be encoded as such, like this:
/.../ "time":"'+ct+'" /.../
But, an even better solution would be to build an object and then stringify this, just like Sam explained in his answer.
var ItemJSON = JSON.stringify({
...
'time': ct,
...
});
If you are working with a library or a framework, chances are it already supports passing JS objects directly, and it will handle converting to JSON itself.
is there a way to send an email via Mailgun with html page as its content that is longer than ~2000 characters?
I have this code, that works perfectly for short html as I believe it is sent in URL address:
var obj = $.request.body.asString();
var req = new $.web.WebRequest($.net.http.POST, "/messages");
req.headers.set('Content-Type', encodeURIComponent("application/x-www-form-urlencoded"));
req.parameters.set("domain", "mailgundomain.com");
req.parameters.set("from", "me#mailgundomain.com");
req.parameters.set("to", 'to#email.com');
req.parameters.set("subject", "subject");
req.parameters.set("html", obj); //email content
In the code above I receive the file and save it to 'org' variable and then send it to mail. What I need is to probably get my "too large" .html file to the body and then show it as a content of the email. As you probably can see, I'm quite new in .xsjs so the more detailed answer the better. If you need any more info, feel free to ask. Thank you.
Edit1: I should add that when I try to send a larger file, the response I get is "414 Request-URI Too Large".
EDIT
This seems to be the right approach, jointly figured out by the OP and myself:
var obj = $.request.body.asString();
var req = new $.web.WebRequest($.net.http.POST, "/messages");
// request headers
req.headers.set('Content-Type', "application/x-www-form-urlencoded");
// request URL parameters
req.parameters.set("domain", "mailgundomain.com");
req.parameters.set("from", "me#mailgundomain.com");
req.parameters.set("to", 'to#email.com');
req.parameters.set("subject", "subject");
// request body
req.setBody(encodeURIComponent(message));
The $.web.WebRequest class sends everything you set in the .parameters collection as an URL parameter, even if the request method is POST. This is perfectly all-right, POST requests may have URL parameters. However, URLs are length-limited, as you have noticed.
The body of a POST request is not length-limited, but you have to do the proper content encoding on your own. The body of a application/x-www-form-urlencoded type request follows the same rules as the URL - key=value pairs separated by & characters.
var obj = $.request.body.asString();
var req = new $.web.WebRequest($.net.http.POST, "/messages");
req.headers.set('Content-Type', "application/x-www-form-urlencoded");
var message = {
domain: "mailgundomain.com",
from: "me#mailgundomain.com",
to: "to#email.com",
subject: "subject",
html: obj
};
req.setBody(urlEncode(message));
where urlEncodedFormat() is a little helper function:
function urlEncode(obj) {
return Object.keys(obj).map(function (key) {
return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
}).join("&");
}
Turning objects into an URL-encoded string is a pretty common operation. It's likely that one of the libraries you use already contains a function that does that.
While the above function is is probably correct (there might be edge cases with undefined or null values), it's preferable not to use a hand-rolled variant. Spend some time looking for the right function in your libraries.
Maybe WebRequest already does the right thing on its own, I have no way to test it, though. Try setting the message object as the body directly:
req.setBody(message);
So I have a form, I took the contents of its inputs, threw them into an array, had it made into a JSON and then sent it to PHP so it can in turn decode and enter it into a database. I know it'd be easier to just use a <form method="POST" action="phpfile.php"> but I can't have this redirecting to another page, especially since my PHP is not embedded into HTML, instead it handles things offsite. Otherwise it'd be simpler to just use $_POST["name"] to get what I need. Nonetheless, this page in particular is supposed to create the user, receive a server response, that the user has been entered into the database and then is given an alert with a button to be redirected to the main page.
So anyway here are the relevant sections of this whole process.
JavaScript:
window.onload = function findSubmitButton() {
var button = document.querySelector(".send_info").addEventListener("click", serverInteraction);
}
function serverInteraction() {
var xmlhttp;
var inputArray;
var finalArray = [];
var JSONArray;
if (window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
throw new Error("Your browser is not compatible with XMLHTTP");
return false;
}
inputArray = document.querySelectorAll("input[type=text]");
for(var i = 0; i < inputArray.length; i++){
finalArray[i] = inputArray[i].value;
}
console.log(finalArray);
JSONArray = JSON.stringify({finalArray: finalArray});
console.log(JSONArray);
xmlhttp.open("POST","phpFiles/sendUserInfo.php", true);
xmlhttp.setRequestHeader("Content-type","application/json");
xmlhttp.send(JSONArray);
}
PHP:
<?php
$finalArray = json_decode($_POST['finalArray']);
var_dump($finalArray);
?>
That var_dump simply returns a null and using echo gives me nothing, except a warning that my array variable isn't initialized through XDebug. I'm not quite sure what I'm doing wrong here, I've been following this just like the tutorials tell you to do it, and isn't generating the array. I've also tried $_POST['JSONArray']without any luck in case that was how it was supposed to go. Also tried file_get_contents('php://input') which sends an empty string as well.
You can't get your data from $_POST if you put JSON in your post body.
see this question Receive JSON POST with PHP. php can't handle application/json properly.
For your var_dump is empty, try this
var_dump(file_get_contents('php://input'));
var_dump(json_decode(file_get_contents('php://input'), true));
you will see your data.
And if you send your data without change it to JSON, you will get wrong data.
eg: your finalArray is ['a','b','c'] and you send it directly.
var_dump(file_get_contents('php://input'));
you will see php got string a,b,c instead of ['a','b','c']
So if you want to use $_POST to receive data, you need to use application/x-www-form-urlencoded. you can use jquery to do it. see http://api.jquery.com/jquery.ajax/
$.ajax({
method: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
it will serialize your js object into x-www-form-urlencoded and php will handle it properly.
use chrome's dev tools, switch to network and see the request payload and response would be helpful for you.
You are bypassing $_POST by sending the the data as "Content-type","application/json" .
The data will instead be set in the body of request and can be retrieved using file_get_contents("php://input")
For further discussion see file_get_contents("php://input") or $HTTP_RAW_POST_DATA, which one is better to get the body of JSON request?
Generally there is no need to send your data as json to php
I am used to sending AJAX requests with jQuery. I now find myself with the task of having to send them using 'vanilla' JS. Using my limited knowledge, I managed to get everything working except for passing the data along with the request. The two variables that are supposed to be being passed along are always filled in as NULL in my database. Every example I have been able to find on here shows the jQuery way, which I have no problem doing.
Can anyone tell me what I am doing wrong? I assume it has something to do with the format of the data, but cannot for the live of me figure it out.
Here is the code for the request. The request object is built in the createXMLHttp() function.
var xmlHttp = createXMLHttp();
var data = {Referrer: document.referrer, Path: window.location.pathname};
xmlHttp.open('post', '/PagePilotSiteHits.php', true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send(data);
var data = {Referrer: document.referrer, Path: window.location.pathname};
function buildQueryString(data)
{
var dataKeys = Object.keys(data);
var queryString = "";
for (var i = 0; i < dataKeys.length; ++i)
{
queryString += "&" + dataKeys[i] + "=" + encodeURICompenent(data[dataKeys[i]]);
}
return queryString.substr(1);
}
xmlHttp.send(buildQueryString(data));
This should do it. The data needs to be passed as a querystring. This functions will create a querystring from the data object you've provided and encodes the uri components as mentioned by #AlexV and #Quentin.
I am only asking the question because I've spent the last 2 days probably reading through countless other questions that are similar and tutorials and still can't get this to work.
I have a local .json file that I want to load up and parse with JavaScript. The file is called 'fakeData.json'. Its format is as such:
{"UIGroup": {"Parent": null, "Type": "public"}}
I'm using this to try to load the file:
<script src="fakeData.json"></script>
I am using this to try to parse the file:
var jsonData = JSON.parse('fakeData.json');
I am getting these errors:
Uncaught SyntaxError: Unexpected token : fakeData.json:1
Uncaught SyntaxError: Unexpected token ILLEGAL : planetPage.html:11
May someone please help me, thanks.
If you want it as simple as it gets, then I would prefix your json content with
var jsonData = {"UIGroup": {"Parent": null, "Type": "public"}}....
which turns your file into a valid js file and then load it with
<script src="fakeData.json.js"></script>
after that, jsonData will have the required content because of literal object notation.
There is no way that you can load a json file into your page otherwise without ajax/httprequest.
You need to get the JSON text into a string variable before you can parse it.
This is generally achieved using the XMLHttpRequest object.
<script src="fakeData.json"></script> will attempt to parse the JSON as JavaScript. This will either throw an error (as it does in your case) or create a data structure and then immediately discard it as it isn't assigned there.
var jsonData;
function reqListener () {
jsonData = JSON.parse(this.responseText);
console.log(jsonData);
};
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "fakeData.json", true);
oReq.send();
If you want to keep it all inline, with a JSON string, and access the object directly you could do something like this:
// copy all the JSON text from the file an keep store it in a local string variable.
var jsonString = '{ "UIGroup": { "Parent": null, "Type": "public" }}';
// parse the string into a JavaScript object
var jsonObj = JSON.parse(jsonString);
// access the object as you usually would
alert(jsonObj.UIGroup.Type);
Fiddle