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.
Related
I saw a lot of problems regarding the exact same thing. But I tried so many thing's that I'm really not sure if what I'm doing even works anymore.
So, I have this multi-dim array, wich I create by looping trough an html table., I want to send it to PHP, so I can loop it, and create the objects I need to store it in a database.
But all I get from PHP when I try to loop it trough a for each is "Warning: Invalid argument supplied for foreach()"
function ReturnFamilyMembers()
{
var Family = [];
var Table= document.getElementById('FamilyTable');
var RowQuantity= Table.rows.length;
for (var i = 0; i < RowQuantity; i++)
{
var Columns= Table.rows.item(i).cells;
var ColumnQuantity= Columns.length;
Family[i] = [];
for(var j = 0; j < ColumnQuantity; j++)
{
Family[i][j] = Columns.item(j).innerHTML;
}
}
var headers =
{
'Content-type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
};
var FamilyArray = encodeURIComponent( JSON.stringify( Family) );
/*console.info( payload );*/
var xhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
/* Add a callback function to process any response from target url ( Worker.php )*/
xhttp.onreadystatechange = function()
{
if( xhttp.readyState == 4 && xhttp.status == 200 )
{
cbReturnFamilyMembers.call( this, xhttp.response );
}
};
xhttp.open( 'POST', 'Worker.php', true );
for( header in headers ) xhttp.setRequestHeader( header, headers[ header ] );
xhttp.send( 'Family=' + FamilyArray );
}
function cbReturnFamilyMembers($resp,$response)
{
alert($resp + $response);
}
}
And the php side...
$Family = json_decode( $_POST['Family'],true);
foreach($Family as $Array) ---> This line launches the error.
{
foreach($Array as $Value)
{
///object creation
}
}
Thank you in advance. I think Im really stucked here, since Im new to PHP, JS and AJAX, everything seems to happen magically. (Can't really say if Im doing thing's the right way.)
I hope Im being clear enough, or tell me please if I can clarify anything.
--------------------------------------****--------------------------------------
EDIT: Im sorry for the late reply and I thank you for your answers. Im going to update the code, so you can see what I have done so far. (Basically I changed the Ajax Part, to be a POST action like you guys said).
I guess I did not explain the whole thing pretty well, this array must be sent trough submitting a form, this function is called on the "onSubmit" (sorry for the lack of explanation). I came to realize I did not have a member in the $_POST array from php that's called "Family", because I got an error of "Index not found", so, I hid an input in the form and called it that way in the NAME property.
In spite of all that, I keep receiving a non-array like value on the php side, (Actually, when I echo it, it prints a one (1)).
Im starting to think of other way's of passing an array, but that's why I used JS and ajax in the first place.
Im doubting of the
"xhttp.send( 'Family=' + Array );" part... is it really posting the array on the index ['Family'] of the $_POST array?, I wonder.
Maybe the array passed as a value is overwritted by the input of the form (That has no value when submitted, actually)
*************************EDIT,AGAIN*****************************************
Changed the code, and worked perfectly.(Added the Cast to an Array object)
$Family = (Array)json_decode( $_POST['Family']);
I didn't notice last night when I posted my initial comment some of the minor errors with your original function, though others have picked up on them and passed comment above - the function was supposedly sending via POST but there were no parameters sent in the send() method, only appended to the url as you would do for a GET request. Also, though not critical I believe, you were not setting any headers with the request and there also is no callback function.
The altered code below does send the contents from a table as intended over POST
<script type='text/javascript'>
/* callback function to handle response data */
function cbReturnFamilyMembers( response ){
alert( response )
}
function ReturnFamilyMembers() {
var Family = [];
var Table= document.getElementById('FamilyTable');
var RowQuantity= Table.rows.length;
for ( var i = 0; i < RowQuantity; i++ ){
var Columns= Table.rows.item(i).cells;
var ColumnQuantity= Columns.length;
Family[i] = [];
for( var j = 0; j < ColumnQuantity; j++ ) Family[i][j] = Columns.item(j).innerHTML;
}
/* XHR headers to be set */
var headers={
'Content-type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
};
var payload=encodeURIComponent( JSON.stringify( Family ) );
/*console.info( payload );*/
var xhttp=window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
/* Add a callback function to process any response from target url ( Worker.php )*/
xhttp.onreadystatechange=function(){
if( xhttp.readyState==4 && xhttp.status==200 ){
cbReturnFamilyMembers.call( this, xhttp.response );
}
};
xhttp.open( 'POST', 'Worker.php', true );
for( header in headers ) xhttp.setRequestHeader( header, headers[ header ] );
xhttp.send( 'Family='+payload );
}
</script>
I'm not a native JavaScript guru (I prefer something like jQuery when it comes to AJAX etc.), but from what I read in your code you do not receive the expected POST data on the PHP side. Looking at your ajax call I see something weird:
xhttp.open("POST", "Worker.php&Family= " +
encodeURIComponent(JSON.stringify(Family)), true);
xhttp.send();
I see that you are using & instead of ? in the GET request.
If I look at the example code on w3schools it shows me something different:
xhttp.open("POST", "ajax_test.asp", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("fname=Henry&lname=Ford");
Try changing your JavaScript code to send data via POST, not GET.
I was trying to see trough thing's that I missed and added some casting on $_POST (Just in case, you know) to be an actual array, and guess what. It worked like a charm. These are thing's that I really hate about php, but I manage.
So, the code on the PHP side stay's like this...
$Family = (Array)json_decode( $_POST['Family']);
And it does not complain anymore about passing an uncorrect argument on for each.,actually It seem's like it casted the Array's inside of the father Array as well, because the nested for each inside of it worked as expected.
Well, Im a litlle more of ashamed of the amount of time that I lost with this thing, but I thank you all for your help, I greatly appreciate it, and It's actually your answers that led me trough get this thing working, (And get the data sending trough $_POST).
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 have a page with an select box, which fires an onChange event. In this Java-Script snippet, I would like to reload the current page, including the GET and POST parameters that where sent during request. AFAIK, this can be achieved by using window.location.reload(), or window.location.href = window.location.href when sending POST data is not required.
However, I need to append an additional value (actually, the value of the select element), additionally to the previously sent element. I do not care whether the data is sent using POST or GET. Is there a way to achieve the desired behavior?
To accomplish this you are going to have to rebuild a request from scratch. In the case of get requests, the arguments are easily accessible in the query string but post requests are a little trickier. You will need to stash all that data in hidden input elements or something so that you can access it.
Then you can try something like this:
var queryString = windlow.location.search; //args from a previous get
var postArgs = $("#myPostArgsForm").serialize(); //args from a previous post... these need to be saved and added to the html by the server
//your additional data... this part you probably need to adapt
//to fit your specific needs. this is an example
var myNewArgName = encodeURIComponent("newArg");
var myNewArgVal = encodeURIComponent("Hello!");
var myNewArgString = myNewArgName + "=" + myNewArgVal;
//if there is no queryString, begin with ?
if(!queryString) {
queryString = "?"
}
//if there is, then we need an & before the next args
else {
myNewArgString = "&" + myNewArgString;
}
//add your new data
queryString += myNewArgString;
//add anything from a previous post
if(postArgs) {
queryString += "&" + postArgs;
}
window.location.href = window.location.hostname + window.location.pathname + querystring
<form id="myPostArgsForm">
<input type="hidden" name="prevQuery" value="whats up?" />
</form>
Pretty simple really; have onChange fire a function that uses getElementById to figure out the selector value and then just use window.location to send the browser to the literal: http://yourdomain.com/yourpage.html?selectval=123
then, in the body onload() method, fire another JS function that checks the "get var" like:
function (GetSelector) {
var TheSelectorWas = getUrlVars()["selectval"];
alert(TheSelectorWas);
}
and do whatever you need to do in that function (document.writes, etc). BTW, posting the actual code you're using is always a good idea.
-Arne
Hi so I have a project for class that is a mix of PHP, HTML, and javascript/Ajax.
One of the requirements is "Execute program.php on server passing it the N/V pairs following the "?" symbol." How do I do this?
First off.. I don't know what NV pairs are and the reading links we were given say nothing about them.. I Googled "Php nv pairs" and literally nothing relative comes up.
I did an in-class activity that upon clicking a button, the url would update and add stuff after the "?" but of course that same code isn't doing it anymore. My professor is terrible at explaining anything and leaves us to follow his typo instructions that aren't even complete..
Here's the code we were given with his comments trying to explain what to do:
// startgame function
// sart button pressed check fields, if OK send to PHP via get request
function startgame(){
//Create the XMLHttpRequest Object
var xmlhttp;
// error handling
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
http = xmlhttp;
// The PHP server script, called with N/V pair with GET request
// Using get request the NV pairs follow "?"
// execute program.php on server passing it the n/v pairs
// that follow the "?"
var url = "program.php?player1name=";
// for this example, only pass to PHP games played
// "&" separates n/v pairs
// player1name is name of algorithm player 1 is using
player1name = document.JForm.p1name.value;
player2name = document.JForm.p2name.value;
gamesplayed = document.JForm.gamesplayed.value;
sdata = url+player1name+"&gamesplayed="+gamesplayed;
// for a "real" solution, pass more data to PHP about state of game
// send get request to server with n/v pairs of screen data
http.open("GET",sdata, true);
// register with server what function to return data
http.onreadystatechange = handleHttpResponse;
// send request to server
http.send(null);
}
Anything will help, thanks!
NV apis means "Name/Value pairs". Basically, in the terms you will be using them in, it is a key connected to its value with an equal sign. For example: username=johnconde. username is the key and johnconde is the value. An example more closely related to your code would be gamesplayed=20. gamesplayed is the key and 20 is the value.
Name/value pairs are commonly found in query strings and it looks like that's what you need to do with your code. You need to build a query string comprised of name/value pairs containing the values you need for your PHP script to do whatever it is it needs to do. It looks like the code already does this and you just need to build the form necessary for this JavaScript to work.
I am trying to parse a sequence of html pages using python, I am having trouble grabbing the pages in iterative fashion. The link to the web page.
Milano Library
After peeking through the source, I found a function that responds to the click event on button element for the next page.
function SaltaAPagina() {
var CalcPag = VAIAPAGINA.value;
if (CalcPag > 0) {
CalcPag=CalcPag;
}
else {
CalcPag="1";
}
document.location = "/OPACMI01/cat/SDW?W=CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend&M=" + CalcPag + "&R=Y";
}
I know that I can encode parameters using pythons urllib2 module using the urlencode method. But I am not sure what I should be including as a parameter
lomba_link='http://www.biblioteche.regione.lombardia.it/OPACMI01/cat/SDW?W%3DCODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend%26M%3D1%26R%3DY'
params = urllib.urlencode([('CalcPag',4)])
# this has not worked.
req = urllib2.Request(lomba_link)
print req
response = urllib2.urlopen(req,params)
html_doc = response.read()
What am I missing here?
Thanks
The javascript function you posted is passing several parameters to the target page:
document.location = "/OPACMI01/cat/SDW" + // This is the path of the page
"?W=CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend" + // The first parameter
"&M=" + CalcPag + // The second parameter
"&R=Y"; // The third parameter
In your code, you've encoded all of the & and = symbols in the URL, so you're passing a single, long parameter with no value - changing those symbols back to what they were in the javascript function should do the trick.
lomba_link='http://www.biblioteche.regione.lombardia.it/OPACMI01/cat/SDW'
params = urllib.urlencode([
('W', 'CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend'),
('M', 4),
('R', 'Y')
])
It's much easier to work with the brilliant requests library, rather than the urllib2 library...
In regards to urllib2.urlopen the params is for POST requests. Unfortunately you need to append the query string to the url to make a GET request.
eg:
req = urllib2.urlopen(req + '?' + params)
With requests, this would be much simpler:
page = requests.get(some_url, params={'CalcPag': '4'})