I have a $.get() call to a PHP page that takes 4 GET parameters. For some reason, despite giving the $.get() call all 4, it only passes the first two. When I look at the dev console in chrome, it shows the URL that gets called, and it only passes action and dbname. Heres the code:
$.get('util/util.php', { action: 'start', dbname: db, url: starturl, crawldepth: depth }, function(data) {
if (data == 'true') {
status = 1;
$('#0').append(starturl + "<ul></ul>");
$('#gobutton').hide();
$('#loading').show("slow");
while(status == 1) {
setTimeout("update()",10000);
}
} else {
show_error("Form data incomplete!");
}
});
and heres the URL that I see in the developer console:
http://localhost/pci/util/util.php?action=start&dbname=1hkxorr9ve1kuap2.db
** EDIT **
I have been informed that I need to encode the URL that I am trying to pass through the header. How would I go about encoding it in javascript, and decoding it in php?
Are you sure that the starturl and depth variables are defined? A simple alert() before the $.get() will be enough to check.
In regards to your edit, you can encode strings in JavaScript with the encodeURIComponent function. And decode it back again in the PHP with urldecode. They both take one string argument.
Probably you will need to check whether your input strings are properly quoted. Internally jQuery will build the paramter string out of the parameter map you specified using its param() method. This method will construct an object of the keys and values, which will likely not be parseable if you quoted your keys and values incorrectly.
# Felix Kling: jQuery automatically encodes keys and values of the parameter string with encodeURIComponent.
Related
I know this has been asked a few times but please bear with me.
I have a google maps object which is rather complex (it contains various nodes, coordinates, etc) and I am trying to pass it as a query string.
I need a play javascript/jQuery solution.
I have tried the .param method which gives a jQuery error. The only thing that works is the "stringify" method which then creates a string that when appearing as a url looks a bit like this: %7B%5C"shape_1%5C"%3A%7B%5C"color%5C"%3A%5C"%237F0000%5C"%2C%5C"data%5C"%3A%7B%5C"b%5C"%3A%5B%7B%5C"Na%5C"%3A51.56727431757122%2C%5C"Oa%5C"%3A-0.10462402858888709%7D%2C....
php translates that as:
{\\"shape_1\\":{\\"color\\":\\"#7F0000\\",\\"data\\":{\\"b\\":[{\\"Na\\":51.56727431757122,\\"Oa\\":-0.10462402858888709},...
but having said that I don't want to use PHP, I am just showing you what it does in case it helps you see what stringify did to the object.
After I unescape with Javascript it looks a bit more normal like:
{\"shape_1\":{\"color\":\"#7F0000\",\"data\":{\"b\":[{\"Na\":51.56727431757122,\"Oa\":-0.10462402858888709},..
So as you can see, the unescaped sequence has these slashes everywhere.
When I try to evaluate that into a JSON object I get "Illegal token \". The parse method also fails. I just can't find any way to put this string back into the complex JSON object that it was.
I have looked online for various suggestions but they fail. I also don't understand why stringify injects all these slashes which simply shouldn't be there.
If anyone has an idea how to take that object, put it in a query string and then parse it back I would be very grateful.
Nick
Update:
The answer is this:
encodeURIComponent(JSON.stringify(myObject));
And then on the receiving end:
var a = querySt("data");
var b = decodeURIComponent(a);
var c = unescape(b);
var d = JSON.parse(c);
or all in one line
JSON.parse(unescape(decodeURIComponent(querySt("data"))));
Nick
See http://php.net/manual/de/security.magicquotes.php - you have to turn off magic quotes. They are old, deprecated stuff, they are insecure and break stuff.
Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed.
Howto: http://www.php.net/manual/de/security.magicquotes.disabling.php
Try this to convert query string into json object
var queryStringToJSON = function (url) {
if (url === '')
return '';
var pairs = (url || location.search).slice(1).split('&');
var result = {};
for (var idx in pairs) {
var pair = pairs[idx].split('=');
if (!!pair[0])
result[pair[0].toLowerCase()] = decodeURIComponent(pair[1] || '');
}
return result;
}
You can use jQuery.param method to covert json object back to query string
I am trying to parse this json data from the url but i get NULL how do i fix this issue.
$source = file_get_contents('http://partners.socialvi.be/e414f702cf3db89a2fe58066bbab369d65b6a058/activities/available.json');
$json = json_decode($source);
var_dump($json);
That's because the API returns the data in JSONP format, not pure JSON. Notice the surrounding onSVJson([]). You'll either have to strip this out, or read the API documentation and try another request format. My guess would be that leaving out the final &callback=onSVJson should do the trick.
That's because if you call the url (go to http://partners.socialvi.be/e414f702cf3db89a2fe58066bbab369d65b6a058/activities/available.json?network_user_id=3459874&max_activities=9&callback=onSVJson with your browser) the json that is returned has no values
Remove the last part of the URL (&callback=onSVJson) and it'll work.
Many APIs offer a feature called JSONP, that allows the JSON to be passed to a callback function, in order to simplify access via cross domain JavaScript. But for PHP you don't need that.
The name of the callback function is typically specified using the callback GET parameter. If you leave that out, no callback function is used - just plain JSON.
I've got a PHP Object, whose properties are initialized the following way:
$this->contact = implode(PHP_EOL,$description->getContact()) . PHP_EOL;
The only exceptions are two properties named version and bugs.
This object is then encoded into a JSON object and passed into the following javascript, which compare the JSON object with value from a form.
function compareEntry(data){
var dataProperties = ["version", "bugs", "scenario", "exception", "instruction", "sources", "risks", "test", "contact"];
var hasChanged = false;
for(var i = 0; i < dataProperties.length; i++){
var dataProperty = dataProperties[i];
alert("Original: '" + data[dataProperty] + "'\nModified: '" + document.myform[dataProperty].value + "'\nTest Value: " + (!data[dataProperty].localeCompare(document.myform[dataProperty].value)));
if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){
hasChanged = true;
}
}
[...]
In the exception of version and bugs, all other properties are compared with the value in the textarea.
The form fields are initialized with the value of the PHP object. When I submit the form the function is called. If I submit the form without changing any value, it still give me a false when comparing a property with the value of a textarea. Why and how could I correctly compare them?
Notes: The PHP Object is a reflection of a MySQL entry which was created with the same form. In between, the information was encrypted and decrypted. But it shouldn't play a role, because the PHP/JSon object and the initial value of the form are from the same source.
EDIT
After the explanation of Frode, I changed my testing statement to:
data[dataProperty].localeCompare(document.myform[dataProperty].value)!=0
But afterwards I noted two discrepencies.
Properties version and bugs which until then returned true when tested return now false. But in the contrary to the other properties, I don't manipulate the values when I'm retrieving them from the database. The value of the property version is stored in a select tag in the form.
And weirder is, when I'm changing one of the value in the textarea, instead of giving me false, it gives me true.
It occured to me that it may be due to the implementation of javascript of the browser I use. But the result I got is not quite as I expected it. Whereas, I've got the described behaviour in Firefox and Chrome, IE and Opera throw always false (with the notable exception of the comparing the version, which gave me true in IE, although he couldn't retrieve the value of the select tag).
Should I maybe use some other method to compare my strings?
EDIT 2
After taking the suggestion of WoLpH, I changed the test condition to:
data[dataProperty].trim() document.myform[dataProperty].trim()
Where trim() is the function described in this other question. And the result are the inverse of what I had in the first EDIT. Except for Chrome who seems to assign it's boolean in random. There seems to be something really wrong in my data in a way.
Here is an example of a JSON object as I can see it in Firefox (variable data in the code snippet).
{"version":"REL-773","bugs":"20831","scenario":"THIS IS A TEST\r\n\r\nThis is the what happens: stuffs.\r\n","exception":"N\/A\r\n","instruction":"1. First Step.\r\n2. Second Step.\r\n2. Third Step\r\nIt is longer.\r\n4. Fourth Step.\r\n5. Fifth Step.\r\n6. Sixth Step.\r\n","sources":"me\r\n","risks":"High risks as it is just for testing of the web application.\r\n","test":"1. Select an entry\r\n2. Change some data such as <HOME>\/path\/\r\n3. See if the application run as expected!\r\n","contact":"me#web.de\r\n"}
EDIT 3
Using the function escape() to escape all special characters of the two strings, I noticed that in the character %OA is written as %OD%OA in the JSON object. It made me suspect that my trimming function doesn't replace correctly the \r\n by \n. (trimming function that I added after the suggestion of the posters here.)
Here is the function I use:
if(typeof(String.prototype.trim) === "undefined")
{
String.prototype.trim = function()
{
return String(this).replace(/^\s+|\s+$/g, '').replace(/\r\n/g,"\n");
};
}
First, Disclaimer: I have the feeling that maybe this isn't the definite answer but more of a workaround. As this is the only way I could deal with this problem.
Now, since I had posted this question, I learned that client-side form validation is not enough. Not only it not enough, but in my case it is not needed as it wouldn't bring anything in the user experience to know that a value has been changed. It is much more interesting for the user to know that a value is not well formatted or just plain wrong. So I migrated the comparison check to the server side.
First I encase my PHP information in a json string, being sure to escape all the relevant characters. I first ensured that the quote symbol was escape correctly, and then I replaced characters which could be problematic by there unicode equivalent, before putting the resulting string in a hidden input of my form.
//escaping ",' and other throublesome characters properly for json
$json_string = str_replace('\'', "\\'", json_encode($objEncasing));
$json_string = str_replace(array('\\"', '\\\'', '&','<','>'), array('\\u0022', '\\\u0027', '\\u0026', '\\u003C', '\\u003E'), $json_string);
echo "<input name='json' type='hidden' value='".$json_string."' />";
One should note that the json object correspond to the information before any change are made in the form, thus why the json string is formatted in PHP. The form information is then sent through POST to a new script which will do all the necessary work.
Now first thing I do in the receiving script, is retrieve the json variable, but one should not forget to check for magic quotes:
if(get_magic_quotes_gpc()){
$json_string = stripslashes($_POST['json']);
}else{
$json_string = $_POST['json'];
}
Now to convert the json object into an array and the you can compare it to the $_POST array (with the exception of the json value):
if(!empty($json_string)){
$json_encasing = json_decode($json_string, true);
$gotChange = false;
foreach($_POST as $key => $value){
if($key != "json"){
//Compare the value, if something change set $gotChange to true
$value = stripslashes($value);
if($value != $json_encasing[$key]){
$json_encasing[$key] = $value;
$gotChange = true;
}
}
}
if($gotChange){
//Do your stuff
}
}
As I'm doing that on my Server, I don't need to anticipate several different behaviour. So my advice is, if you can help it, do your stuff server-side.
Javascript's string.localeCompare returns 0 if the strings compared are identical, and -1 or 1 otherwise. So your if clause:
if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){
hasChanged = true;
}
.. will in fact set hasChanged to true when the strings are equal. Try removing the ! and see if it behaves as you expect.
I'm trying to return data as an array to my .ajax function on success so I can do do multiple things, but I can't get to work for anything except a single value. Like return $foo. But when I return $array, the page never loads up.
JavaScript's use & utilizing of array is different as compared to PHP's processing. So, either you need to send the data to your AJAX function as a JSON (JavaScript Object Notation), otherwise you need to send the data as a string with a common separator to your AJAX function.
In the latter case, you will need to split up the Response Text in your AJAX function, with that common separator, to make up a JS Array. Then it will be very much easy to use that array instead.
Hope it helps.
You would have to serialize your data into a string. My preference is JSON, so if your PHP version is >= 5.2.0, you'll most likely have access to a json_encode function. This will turn the PHP object into a JSON string. If you don't have access to json_encode, you can use the PECL JSON package.
Looking at the way you reference your ".ajax" function, I am assuming jQuery. So as long as you set the content type to 'json', the JSON response will result in a native JavaScript object. For example,
PHP,
return json_encode(array(1, 2, 3));
JavaScript,
$.ajax({
...
contentType: 'json',
success: function(response) {
for (var i = 0; i < response.length; i++) {
alert(response[i]);
}
});
This code should proceed to alert 1, 2, and then 3.
I haven't verified the code, but the essential parts are all there. A note to have though, a normal indexed array is turned into a JavaScript list while an associative array will be turned into a JavaScript object.
JSON is a good option to send your data array from PHP to Javascript. In PHP side just encode and return your data array as JSON string and in the Javascript side decode that JSON string and use as normal array.
Suppose your data array is like $array, in your PHP code just encode that array using json_encode($array) and return the resulted JSON string.
In your javascript code decode that JSON string using 'eval' function in the success callback function like:
$.ajax({
type: "GET",
url: "test.php",
success: function(data) {
var dataArray = eval('(' + data + ')');
}
});
I think this will help you ...
Siva
I'd like to pass content back and forth from PHP to jQuery and vice versa. I'm not sure if I fully understand the best way to go about this and am hoping for some best advice and clarification.
Below is an example of something I'm trying to do. The PHP lists the files in a directory (whose path is passed to it from jQuery), stores them in an array, then passes them back to jQuery. I'd like to use the values in that array for various purposes but really I just want to understand passing information back and forth between the two, wether it's from an array, or just a plain variable. Merci beaucoup!
The PHP:
$files = array();
$dir = ($_POST['dir']);
$count = 0;
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && strpos($file, '.jpg',1)) {$count++;
$files[$file] = $file;
}
}
closedir($handle);
}
echo json_encode($files);
?>
The jQuery:
$(document).ready(function(){
$('a').click( function(e) {
e.preventDefault();
$.post("php.php", 'path/to/directory/',
function(data) {
alert(data);
}, "json");
});
});
If I read your question correctly, you're not really looking for tips on this specific code, but more for comments about the process of transferring data back and forth between PHP and jQuery. Let's look briefly at JSON itself, and then look at each side of the communication.
JSON
JSON is a simple way of representing collections of data in a string format that is pretty easy for both humans and computers to read. You can get the full description at http://www.json.org/ but it basically boils down to:
data is enclosed by { and } characters
data is in the format string : value, where the string acts as a reference label
string is in the format of ", followed by any unicode char except / or ", followed by another quote
value can be another string, a number, a complete data object, a boolean value, or an array of some set of the above values
an array is of the format [, followed by a comma separated list of values, followed by a ]
PHP
On the php side, you are receiving a page request and using the attached parameters to decide how to process the page. For a JSON app, that means loading the data into an array, and then the json_encode() function does the grunt work for converting that array into JSON format. The rest of the app would work just the same if you manually created the JSON as a string, though obviously this would make for a lot more work in the PHP code for you. Hence the helper function :)
jQuery
On the jQuery side, the call to $.post() issues an AJAX request, to retrieve a page from the server. In this case, you are sending a request to php.php.
The second set of parameters in the $.post() call is a collection of parameters, which should consist of { followed by comma-separated sets of: a label, then a colon, then a value. Once you have specified all parameters, close the collection with a }. Note that though this is similar to a JSON string, it is not JSON. The label does not have quotes around it the way JSON requires. Any string values, however, do need quotes.
The third parameter of the $.post() call is a function that will be automatically applied to the data that is received from the page request. The results of the function are automatically loaded into whatever variable you specify in the function definition, and you are able to use that data within the function, pretty much as you please. In your example, you simply sent the data to an alert box, but you can do much more with it. You could actually parse this as a JSON collection and perform various actions based on the contents of individual components from within the JSON (which, ultimately, means that you are directly acting on individual values from the original php array).
The fourth parameter on the $.post() call is the data-type. It isn't required, however using it is required if you want to access the json collection as more than just a string. With it, you can specify that the type of data you are returning is json, by simply including "json". If you have done this, you can access the elements of the JSON collection directly within the third parameter function, by referencing their label.
Here's an example of a complete JSON $.post() call:
$.post("test.php", { "func": "getNameAndTime" },
function(data){
alert(data.name); //pretend it's John
console.log(data.time); //pretend it's 10:05am
}, "json");
So here, an ajax request is sent to test.php with the parameter func="getNameAndTime" which the php uses to determine that it should return a json-encoded collection of the form {"name":"John", "time":"10:05am"}, and then the response reaches the function specified to first alert() with the value "John" and then log "10:05am". Again, the only reason that data.name and data.time works in this function is because we specified that json was the return type in the fourth parameter.
The code is correct except for this line in the jQuery:
$.post("php.php", {dir: 'path/to/directory/'},
By the way, it looks like your request is idempotent, so consider using GET instead of POST.