cross domain request data using pure javascript - javascript

I am trying to access an external url which returns json data and based on one of the value in that data I need to hide a table row. I have tried several options to do this with jsonp, jquery and ajax but nothing seem to work. YQL is working for me but I can't use outer Service as the code need to be independent. Please someone let me know how I can make this work with javascript
This is one approach I have tried
<script type='text/javascript'>
function checkBlueLight() {
$('#trBlueLight').hide();
$.getJSON('http://.../Lights/getBlueLight?callback=?', function (data) {
if (data.expDate != null) {
$('#trBlueLight').show();
} else {
$('#trBlueLight').hide();
}
});
}
</script>
This is another approach I have tried. same issue unauthorized - 401
$.ajax({
url: 'http://.../Lights/getBlueLight',
dataType: 'json',
success: function(data) {
if (data.expDate != null) {
$('#trBlueLight').show();
} else {
$('#trBlueLight').hide();
}
}
});
I have even tried to get data from url using jsp with and that also causing some permission issue

Do you control the external url? Because you can do:
On your local page:
function your_function(data) {
alert(data.message)
}
And then on http://www.include.me/remote.php (or whatever is returning JSON) you would have it return
your_function({message: "it works!"});
And then back on your local page:
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://www.include.me/remote.php");
document.getElementsByTagName("head")[0].appendChild(script);
Which will then include the script, which simply tells it to run your already defined function with the data it provides.

If you can't control the external URL, and it doesn't support CORS nor JSONP, then you best option is to write a server side proxy method for the service. So on your server, you expose a new endpoint on your own host that on the server side access the real service on your clients behalf, and returns the result to your client.

For using jsonp, the server should bind the return type with a callback function. If it not, you cannot get the data from server.
If you are using cors, server should support that. Which means server should set,
"Access-Control-Allow-Origin" header to "*"

The issue with JS or jQuery is that crossdomain data may not be possible depending on the browser or server or a combination of both that prohibits the data exchange. This is security policy on many browsers and servers.
The best and safest choice is using a combination of JS or jQuery (Ajax call) with PHP cURL where the cURL will make the call requesting the data xml/json format and then sent back to the Ajax request.
Please take a look at the following example:
In the JS/JQuery AJax script:
$.ajax({
url: 'php_script_with_cURL.php',
dataType: 'json',
data:'THE_DATA_OR_REQUEST',
type:'post',
success: function(data) {
if (data.expDate != null) {
$('#trBlueLight').show();
} else {
$('#trBlueLight').hide();
}
}
});
and then in the php file (must be in the same server as your JS):
(you can use url string or post to request the data)
//USE POST IF YOU NEED TO SEND VARIOUS COMMANDS TO GET THE DATA BACK
$post = $_POST;
//INIT THE CURL CALL
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
//this will tell the server how to return the data format
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
//use the query string if require, if not just remove it
CURLOPT_URL => 'http://THE_URL_HERE.COM?request_value=some_value',
//use the post only if yo need to post values
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
value1 => $post['value1'],
value2 => $post['value2']
)
//alternative you can also pass the whole POST array
//CURLOPT_POSTFIELDS => $post
));
$data = curl_exec($curl);
if(!$data){
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
curl_close($curl);
//echo the data that will be sent to the JS/JQuery Ajax call
echo $data;
//or if you need to do more processing with php
//$response = json_decode($data);
Hope this helps :)
Happy coding !

Related

Add javascript variable inside PHP code to decrypt JSON

Basically I have a combination of PHP codes and javascript codes. My mySQL data are encrypted using CodeIgniter, thus to load the data (view and edit) in json, i need to decrypt it again. My question is how to make my "$x" variable dynamic?
Thanks.
function edit_person(id)
{
save_method = 'update';
$('#form')[0].reset();
$('#modal_form').modal({backdrop: 'static', keyboard: true, show: true });
<?php
$x = 13; //<== **i need to make this $x dynamic based on "edit_person(id)"** //
$url = "http://myurlhere.com/main/ajax_edit/".$x;
$datax = file_get_contents($url);
$string = json_decode($datax, TRUE);
?>
$.ajax({
url : "<?php echo site_url('main/ajax_edit')?>/" + id,
type: "GET",
dataType: "JSON",
success: function(data)
{
$('[name="id"]').val(data.id);
// ** below code "firstName" is my decryption requirement ** //
$('[name="firstName"]').val("<?php echo $this->encryption->decrypt($string['firstName']); ?>");
$('#modal_form').modal('show');
},
error: function (jqXHR, textStatus, errorThrown)
{
alert('Error get data from ajax');
}
});
}
You are probably confusing the server-side and the client-side code.
In simple terms: First, the client sends a request to the server. The target PHP code gets executed on the server-side only. It then generates an HTML file, which contains your JS code. This file is sent to the client and is executed on the client-side only. At that time, on the client-side, there is JS code only and no PHP code anymore. All the PHP code gets replaced by some value or is simply removed or ignored.
If you want to access some PHP functionality from your JS code, you have to send a request from the client to the server. As you are doing with the AJAX call.
So in order to make your $x dynamic, you have to call some PHP code and pass the ID as a parameter.
In a strongly simplifyed way you could achieve this by:
$.ajax({
url : "your url to some file.php/?id=" + id,
type: "GET",
})
some file.php
<?php
$x = $_GET["id"]; //<== $_GET["id"] will return the value of the parameter "id" in the url
?>
Starting from here, you should read more about AJAX calls, input sanitation and validation in order to secure your requests.

can not Send data to php file using ajax

I have this php file graph.php
$host = $_POST['hostname'];
echo $type=$_POST['type_char'];
include('rrdtools.inc.php');
include('graphs/'.$type.'.inc.php');
and I trying to send data to this file using this ajax code
var type_char='fortigate_cpu';//$('#graph').val();
var hostname='10.10.0.144';//$(this).attr('id');
//$('#device_host').val(id);
$.ajax({
type: 'POST',
url: 'SNMP/graph.php',
data: { hostname:hostname,type_char:type_char },
success: function(data) {
alert(data);
// show the response
$("#grph").attr("src", 'SNMP/graph.php');
console.log(data);
}
});
the result when I send data to that file is
fortigate_cpu as a value of type_char variable
when I opened error.log file in apache logs
I have this message
include(): Failed opening 'graphs/.inc.php' for inclusion (include_path='.:/usr/share/php')
as you see the value of fortigate not included in include function even if the char_type variable is send by ajax and printed in page
include file must be as this
include( 'graphs/fortigate_cpu.inc.php')
why type not included in the include session even if the variable is received from ajax
As was mentioned by other users in the comments, maybe your issue is that you are setting type to a different value after including rrdtools.inc.php .
Try randomizing ( changing the name), of the type variable:
$host = $_POST['hostname'];
echo $type123456=$_POST['type_char'];
include('rrdtools.inc.php');
include('graphs/'.$type123456.'.inc.php');
It's the only thing I can think of, since both I (and others) have tested your code.
(both front-end and back-end).
PS: Include using post param is a bad practice.

Securing an AJAX service call in jQuery and PHP (with session token)

I'm currently building a framework in which for example form submit's are being implemented as jQuery ajax calls to a .php (service) file.
Part of the jQuery for reference:
var dataSerialized = $(form).serialize();
var service = $(form).attr("action");
$.ajax({
url: "services/" + service + ".php",
data: dataSerialized,
type: "POST",
cache: false,
dataType: "json",
success: function(json) {
$(json).each(function() {
loadPage(this.callback);
});
},
error: function(json, message) {
finalError(message);
}
});
And the .php does currently nothing more than:
include_once("../content/includes/connect.php");
include_once("_functions.php");
//TODO: support sending variables
$check = true;
$callback = "error";
foreach ($_POST as $key => $value) {
list($pass, $errormessage) = checkRules("register", $key, $value);
if (!$pass) {
$check = false;
$callback = "error";
break;
}
}
if ($check) {
$callback = "register_success";
}
echo json_encode(array(
"callback" => $callback
));
SQL::close();
Now I want the service call to be as secure as possible, given my situation, I see the following options:
SSL cannot be used, as it is relatively too expensive. Just working on a homebred project, nothing important.
jCryption library cannot be used, as I'm on a cheap web hosting and do not have access to the server itself.
OAuth 2.0 is a possibility, but seems quite complicated.
$_SERVER variables can be used to help protecting the service .php pages, but not reliable.
$_SESSION could be used to generate tokens.
I already implemented an easy measure: Change GET to POST. This will only deter the most easy attack, now the attacker actually needs to use some tampering tool instead of being able to do it directly through the browser.
I think I can protect every call that comes from an URL typed in the browser, however I see two serious threats:
Direct requests to the webserver: The attacker can pass any data he wants.
Using a Browser JavaScript Console to send custom jQuery requests.
I think it is best, again under these circumstances, to try to protect the service .php pages with $_SESSION tokens, but how exactly do I go about these?
They need to be set as some point in time before the service call, and then the service call could check it.
I also have access to a MySQL database and of course plain text files on the webspace.
Can anyone help me out any further?
Have a csrf token send together with the form and in your .php file you could use something like this
session_start();
if ($_SERVER['HTTP_X_CSRF_TOKEN'] !== $_SESSION['csrfToken']) {
return false;
die();
}
Send CSRF Token with all service calls
$.ajaxSetup({
headers: {
'X-Csrf-Token': "TOKEN HERE"
}
});

how to run a MySQL query using JavaScript

I want to run MySQL query's on command without reloading the page. I think JavaScript can do this but i am unsure how. What i want to do is have a form with an return id field and when you fill out the form once with the return id and come back later and use that return id and it fills in in a lot of the content for them to save time.
Javascript cannot run MySQL Queries itself; however, you can use ajax to make a call to the server to retrieve the data. I like to use jQuery's ajax() for my ajax needs.
Here is an example of how jquery's ajax() method works:
$.ajax({
url: "pathToServerFile",
type: "POST",
data: yourParams,
dataType: "json"
});
You can't query with pure javascript. It has to be done from a hook that is setup on a backend.
This tends to be done with ajax.
Moreover, if querying were available from client side, then everyone could see your connection string.
You'll need to have a backend script do the query - JavaScript, being an entirely client-side language, has no say-so in what goes on with your MySQL server.
What you'll need to do is pass the parameters you want in your query to whatever server-side language you're using via AJAX, and have the script create and process the query as you wish.
DO NOT create the query in javascript and pass it to the server - this is VERY unsafe as it allows anyone to run whatever queries they want.
Using ajax will do the job. But you'll still need a server-side language for the ajax to call to.
Using jquery with ajax will be even quicker!
$.ajax({
type: "POST",
url: "someserversidelangfile",
data: "" //pass data through this variable
}).done(function( msg ) {
//do so
});
Everyone's all about ajax so here's an example on how to send data with vanilla JavaScript and fetch the response back. It will be a nonsense example and will use non-PDO MySQL connection. Backend is PHP, but script.js file is practically the same for NODE.js backend.
script.js
/* mode options are cors, no-cors (only send, no response) and same-origin */
fetch('not-ajax.php', {
method: 'post',
mode: 'same-origin',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json', // sent request
'Accept': 'application/json' // expected data sent back
},
body: JSON.stringify({
/**
* FYI: For this particular case you would actually prefer to have this snippet
* just before ending </body> tag so it get's actual width of the window minus
* the width of the scrollbar if there is one. If you use it in an external
* script it's the same as using window.innerWidth and window.innerHeight.
**/
'screen_width': document.documentElement.clientWidth,
'screen_height': document.documentElement.clientHeight
})
})
/**
* You need this part as well if you send json-encoded data back from backend.
**/
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
not-ajax.php
<?php
include 'connection.php';
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if ($contentType === "application/json") {
// Receive the RAW post data.
$content = trim(file_get_contents("php://input"));
// $decoded can be used the same as you would use $_POST with ajax
$decoded = json_decode($content, true);
/**
* Sure enough you can use a SELECT statement, get the data from the database,
* manipulate it to your heart's content, and then send it back to fetch
* function in JavaScript for further manipulation and usage.
**/
$sql =
"INSERT INTO used_screen_dimensions (
) VALUES ( ?, ? )";
$statement = $connection->prepare($sql);
/**
* first parameter is a string with characters
* 'i' for integer,
* 'd' for double,
* 's' for string,
* 'b' for blob
* in the respective order to all other binded parameters
**/
$statement->bind_param('ii', $decoded['screen_width'], $decoded['screen_height']);
$result = $statement->get_result();
$statement->close();
/**
* You may only echo out one thing, but it doesn't have to be a boolean.
* You can (and should) echo an object with more info including what error
* it is.
**/
if(! is_array($decoded)) {
echo 0; //If json_decode failed, the JSON is invalid.
return;
} else {
// Send error back to fetch.
if (!$result) {
echo 0; // couldn't insert to database
return;
}
echo 1; // Success
}
} else {
echo 0; // Wrong content type
}
Don't know why I went and typed this answer out by hand. There's bound to be errors.
JavaScript can't run MySql commands.You can use JQuery with Ajax.
like this :
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});

Both .getJSON() and .ajax() not working for REST API call

Can someone explain me how to make a REST call using jQuery/Javascript? I tried using the .getJSON() and .ajax(), but neither helped me.
This is the REST URL :
http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode?zipcode=94954&date=2010-01-15&format=json&key=API_KEY
Code:
$.getJSON('http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode?zipcode='+zip+'&format=json&key=**<KEY HERE>**',
function(data)
{
alert(data.AQI);
}
);
$.ajax({
url: 'http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode',
type: 'GET',
data: 'zipcode='+zip+'&format=json&key=**<KEY HERE>**',
success: function() { alert('get completed'); }
});
there are a couple of problems. First, you need to add &callback=? to the end of the querystring to allow the crossdomain.
$.getJSON('http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode?zipcode=94954&format=json&key=B868EA39-1D92-412A-96DE-DCF5ED30236D&callback=?',
function(data)
{
alert(data.forecast[0]);
}
);
You will then get an Uncaught SyntaxError: Unexpected token : error. This is because you are expecting json data, but the headers on the server are sending text/html - not application/json. Take a look at the console when you run this fiddle, you'll see the errors.
Therefore, you can't get the data from cross domain because you have to be using jsonp - which requires the header to be sent correctly.
If this is your api, then you just need to send the correct header, otherwise, you need to get with the developers there and ask them to fix it.
Alternatively
If neither of those above options work, you could always create a proxy script that would get the contents of the json feed for you and echo it out. Here's one in PHP:
<?php
// myproxy.php
header('Content-type: application/json');
$zip = $_GET['zip'];
$results = file_get_contents('http://ws1.airnowgateway.org/GatewayWebServiceREST/Gateway.svc/forecastbyzipcode?zipcode=' . $zip . '&format=json&key=B868EA39-1D92-412A-96DE-DCF5ED30236D');
echo $results;
?>
Then, you would just point your $.getJSON to this script on your server:
$.getJSON('/myproxy.php?zip='+zip,
function(data)
{
var mydata = jQuery.parseJSON(data);
alert(mydata.forecast[0]);
}
);

Categories