I know the question of passing Json from servlet/Jsp to javascript has been asked a lot, but my Json object is huge and contains around 400 records.
I have tried passing it from jsp to javascript as follows:
var json = ${json};
but the json object breakes and doesn't finish till the last record. When i print the json object in the servlet it has no breaks. I basically have a servlet which generates a JSON result and passes it to a JSP file and i want the result to be used to plot poly-lines and points on google map. There is no request being sent form the jsp to my servlet.
I am really a novice coder.
I use RequestDispatcher to send the data to jsp as follows:
request.setAttribute("json", json1);
RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp");
dispatcher.forward(request, response);
While execution the HTML page is not completely generated:
HTML-break
The jsp code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO- 8859-1">
<title>Insert title here</title>
<script src="http://maps.googleapis.com/maps/api/js">
</script>
<%
JSONObject json = (JSONObject)request.getAttribute("json");
%>
<script>
var json = ${json};
function initialize() {
//Set of statements
}
</script>
</head>
<body>
<div id="googleMap" style="width:1000px;height:1000px;"></div>
</body>
</html>
The problem is in the statement var json = ${json};
Related
Down below you can see I have a nodeJS server which passes down a data object to the index page. Inside of my index.ejs file I can receive this data using <%= data %> however this only gives [object Object]. However, what I want is to receive this data inside my javascript file as an acutal object so I can use the data to do stuff. How can I acheive this?
NodeJS:
router.get("/", getData, (req, res) => {
res.render("index", { data: data }); // Where 'data' is a large object with lots of information
});
index.ejs:
<html>
<head>
...
<script defer src="myScript.js"></script> <!-- I want to pass the data object to this file -->
</head>
<body>
<%= data %> <!-- This works, but is not what I want -->
</body>
</html>
myScript.js:
const data = <%= data %> // this doesnt work, but is what I need
JSON is a data exchange language based on literal syntax for JavaScript. So long as your data consists entirely of data types supported by JSON (such as plain objects and numbers) you can use it to generate a string that you can insert into a data attribute and parse with `JSON.parse.
<script data-data="<%= JSON.stringify(data) %>">
const data = JSON.parse(document.currentScript.dataset.data);
</script>
If your object includes features not supported by JSON, such as functions, symbols, etc. then you'll need to special case how they are transferred across.
An earlier version of this answer used a similar technique that treated the JSON as JavaScript source code. This more-or-less works, but is vulnerable to XSS since if the data contains a string "</script>" that will terminate the script element in the middle of the string literal. There is a potential that further data in the string could pose a more serious XSS threat.
You could use that technique, but you would need to mitigate that attack by escaping / characters.
Try like this:
<html>
<head>
...
<script>var data = <%= JSON.stringify(data) %>;</script>
<script defer src="myScript.js"></script> <!-- I want to pass the data object to this file -->
</head>
<body>
</body>
</html>
UPDATE
Security concern: If your object contain user supplied datas, your page will possibly become subject to injection
While trying to iterate a map in a javascript function by passing key as below:
<html> <head>
<script type="text/javascript">
function demo(tmp){
<c:forEach var="user" items="${usermap}">
<c:out value="${usermap.get(\"+'tmp'+\").name}"></c:out>
</c:forEach>
}
</script>
<title>Insert title here</title> </head>
<body>
<h1 onclick="demo('user1')">User VO</h1>
<c:forEach var="user" items="${usermap}">
Key: ${user.key} - Name: ${user.value.name} - Id: ${user.value.userid}<br/><br/>
</c:forEach>
</body> </html>
I am getting blank value. But when I hard code the value of key***user1***, it works.
Servlet Code
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//System.out.println("in servlet doGet:"+ ++count);
UserVO user1= new UserVO("Y","701");
UserVO user2= new UserVO("D","834");
hmap.put("user1", user1);
hmap.put("user2", user2);
//hmap.values()
request.setAttribute("usermap", hmap);
//response.sendRedirect("User.jsp");
RequestDispatcher view = request.getRequestDispatcher("User.jsp");
view.forward(request, response);
//response.getWriter().append("Served at: ").append(request.getContextPath());
}
Can somebody help me here?
The Issue:
You are mixing client side and server side code. JavaScript and JavaServer Pages are executed separately.
JSP code is compiled on the server,
The result is a HTML, that is delivered to the browser
In the browser the JavaScript is executed
So JSP related stuff like:
JSTL, JSP Standard Tag Library (tags like <jsp:something> <c:something>)
JSP-EL, Expression Language (strings like ${something})
is processed on the server.
You can see, what HTML code is received in browser, by pressing Ctrl+U in Firefox/Chrome.
In your case:
Selecting an option in the select-tag is executed on the client side in browser.
It is too late for EL-evaluation. The EL has bean already evaluated.
You can use ajax to request the needed data (map) according the user selection.
EDIT:
The EL of the hardcoded line is executed on the server and replaced with the value. On the other case, when select-tag is involved, the EL was executed on the server and replaced by var Cfs_id ="";. So the dummy function ignore the parameter serviceId and set the variable always to empty string.
Look the code in your browser. There is only Html and Javascript. The JSP EL are no more there.
This question already has answers here:
How do I pass JavaScript variables to PHP?
(16 answers)
Closed 2 years ago.
How do I pass have a Javascript script request a PHP page and pass data to it? How do I then have the PHP script pass data back to the Javascript script?
client.js:
data = {tohex: 4919, sum: [1, 3, 5]};
// how would this script pass data to server.php and access the response?
server.php:
$tohex = ... ; // How would this be set to data.tohex?
$sum = ...; // How would this be set to data.sum?
// How would this be sent to client.js?
array(base_convert($tohex, 16), array_sum($sum))
Passing data from PHP is easy, you can generate JavaScript with it. The other way is a bit harder - you have to invoke the PHP script by a Javascript request.
An example (using traditional event registration model for simplicity):
<!-- headers etc. omitted -->
<script>
function callPHP(params) {
var httpc = new XMLHttpRequest(); // simplified for clarity
var url = "get_data.php";
httpc.open("POST", url, true); // sending as POST
httpc.onreadystatechange = function() { //Call a function when the state changes.
if(httpc.readyState == 4 && httpc.status == 200) { // complete and no errors
alert(httpc.responseText); // some processing here, or whatever you want to do with the response
}
};
httpc.send(params);
}
</script>
call PHP script
<!-- rest of document omitted -->
Whatever get_data.php produces, that will appear in httpc.responseText. Error handling, event registration and cross-browser XMLHttpRequest compatibility are left as simple exercises to the reader ;)
See also Mozilla's documentation for further examples
I run into a similar issue the other day. Say, I want to pass data from client side to server and write the data into a log file. Here is my solution:
My simple client side code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" type="text/javascript"></script>
<title>Test Page</title>
<script>
function passVal(){
var data = {
fn: "filename",
str: "this_is_a_dummy_test_string"
};
$.post("test.php", data);
}
passVal();
</script>
</head>
<body>
</body>
</html>
And php code on server side:
<?php
$fn = $_POST['fn'];
$str = $_POST['str'];
$file = fopen("/opt/lampp/htdocs/passVal/".$fn.".record","w");
echo fwrite($file,$str);
fclose($file);
?>
Hope this works for you and future readers!
I'd use JSON as the format and Ajax (really XMLHttpRequest) as the client->server mechanism.
Using cookies is a easy way. You can use jquery and a pluging as jquery.cookie or create your own.
Using Jquery + jquery.cookie, by example
<script>
var php_value = '<?php echo $php_variable; ?>';
var infobar_active = $.cookie('php_value');
var infobar_alert = any_process(infobar_active);
//set a cookie to readit via php
$.cookie('infobar_alerta', infobar_alerta );
</script>
<?php
var js_value = code to read a cookie
?>
I've found this usefull Server-Side and Hybrid Frameworks:
http://www.phplivex.com/
http://www.ashleyit.com/rs/
I've been using Ashley's RSJS Script to update values in HTML without any problem for a long time until I met JQuery (ajax, load, etc.)
There's a few ways, the most prominent being getting form data, or getting the query string. Here's one method using JavaScript. When you click on a link it will call the _vals('mytarget', 'theval') which will submit the form data. When your page posts back you can check if this form data has been set and then retrieve it from the form values.
<script language="javascript" type="text/javascript">
function _vals(target, value){
form1.all("target").value=target;
form1.all("value").value=value;
form1.submit();
}
</script>
Alternatively you can get it via the query string. PHP has your _GET and _SET global functions to achieve this making it much easier.
I'm sure there's probably more methods which are better, but these are just a few that spring to mind.
EDIT: Building on this from what others have said using the above method you would have an anchor tag like
<a onclick="_vals('name', 'val')" href="#">My Link</a>
And then in your PHP you can get form data using
$val = $_POST['value'];
So when you click on the link which uses JavaScript it will post form data and when the page posts back from this click you can then retrieve it from the PHP.
You can pass data from PHP to javascript but the only way to get data from javascript to PHP is via AJAX.
The reason for that is you can build a valid javascript through PHP but to get data to PHP you will need to get PHP running again, and since PHP only runs to process the output, you will need a page reload or an asynchronous query.
the other way to exchange data from php to javascript or vice versa is by using cookies, you can save cookies in php and read by your javascript, for this you don't have to use forms or ajax
I have to pass a jQuery plugin some data. I could either pass it a URL where it will use a GET request to fetch the data, or directly pass it an array which will eliminate one server request. The data in question is user provided and not sanitized upon database entry.
The below script doesn't show the plugin, but does show how I might pass the data to the client so it may be directly passed to the plugin. As seen, the dynamically generated JS approach is suspect to XSS, however, the Ajax/JSON approach doesn't seem to be.
For this scenario, how should the dynamically generated JavaScript approach be secured, and is there risk to the Ajax/JSON approach?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XSS Testing</title>
<script src="getStuff.php?type=js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
console.log(stuff);
$.get( "getStuff.php", function( data ) {
console.log(data);
},'json');
});
</script>
</head>
<body>
</body>
</html>
getStuff.php
<?php
$getFromDB=array(
'Mary',
'x"];alert(\'xss2\');x=["x',
'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
header('Content-Type: application/javascript;');
$s='var stuff=[';
foreach($getFromDB as $row) {
$s.='"'.$row.'",';
}
$s=substr($s, 0, -1).'];';
echo($s);
}
else {
header('Content-Type: application/json;');
echo(json_encode($getFromDB));
}
?>
if you expect to work with JSON, why not first and foremost verify that's what you're working with?
$.get(...)
.success(function(data) {
try {
JSON.parse(data)
} catch (e) {
console.error("this isn't actually JSON");
}
})
JSON cannot contain functions, nor function calls, so just asking the browser to see if it can be parsed should be enough to make it go "there is stuff in here that isn't real JSON data".
The same goes for your PHP of course. Never build a string if you need a specific serialization. In this case, construct your key/map object the usual PHP way, and then use the built in json_encode function for converting that to a legal JSON serialization, instead.
It's almost like you've designed your example to be susceptible to hacking. You're doing nothing in the "js" case to ensure that the data is output with proper escaping, you're only doing it in the "json" case.
If you're going to include a JavaScript file that's purely data, like this:
<script src="getStuff.php?type=js"></script>
Then getStuff.php needs to ensure what it sends back is properly escaped as data:
<?php
$getFromDB=array(
'Mary',
'x"];alert(\'xss2\');x=["x',
'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
header('Content-Type: application/javascript');
echo('var data = ');
echo(json_encode($getFromDB));
echo(';');
}
else {
header('Content-Type: application/json');
echo(json_encode($getFromDB));
}
?>
And boom: No alert.
Side note: You shouldn't have the ; on the end of the Content-Type strings. I've removed them in the above.
This is format of JSON data: [{"options":"smart_exp"},{"options":"user_int"},{"options":"blahblah"}] that I receive through getjson from server. I need to append json with user input. I am trying to do it in this way: 1st convert it into javascript object, append it with user input, again convert to json object & send it back to server for database update. I have converted json to javaScript object using eval(). Now not able to manipulate javascript object. If I convert javascript object back to json object, it displays correctly all data that was sent from server.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head></head>
<body>
<form name="index">
<p><input type = "text" id = "txt" name = "txt"></input></p>
<p><input type = "button" id = "send" name = "send" value = "send"
onClick="ADDLISTITEM();"></input></p>
<select name="user_spec" id="user_spec" />
</form>
<script>
function ADDLISTITEM()
{// this script suffers from errors on eval/JSON.parse methods
alert (json.length);//outputs corrcet with eval
tring = JSON.stringify(json);//outputs corrcet with eval
alert(jsonString);//outputs corrcet with eval
alert(json.options[0]);//no output
}
</script>
<script src="http://code.jquery.com/jquery-latest.min.js">
</script>
<script src="http://www.json.org/json2.js"></script>
<script>
var json;
$(document).ready(function() {
jQuery .getJSON("http://127.0.0.1/conn_mysql.php", function (jsonData) {
json = eval(jsonData);
//json = JSON.parse(jsonData);/*error if uncomment:"IMPORTANT: Remove this line from
json2.js before deployment"*/
$.each(jsonData, function (i, j) {
document.index.user_spec.options[i] = new Option(j.options);
});});
});
</script>
</body>
</html>
In jQuery, $.getJSON()'s callback gets called with parsed JSON data; just use it.
$.getJSON("*.php", function(data) {
$.each(data, function() { alert(this.options); });
);
should give you an alert for every {"options": "xyzzy"} object in the array.
EDIT after OP edited their post:
Your edit clarifies things a little: You won't get any data back -- and it will be completely silent, too, as I found out -- if you violate the same origin policy.
Basically (with exceptions (preflight checks, etc)), you can only access URLs on the exact same domain via AJAX. If your HTML file is a static file served locally, it can not access http://127.0.0.1/; if your file is http://foo.baz.quux.org/, you can't simply AJAX into http://mordor.baz.quux.org .
I don't think the problem here has anything to do with eval/parse etc or the same origin policy. Your json is an array of objects each containing a member named options. Therefore you cannot do json.options[0], you have to do json[0].options.
var json = [{"options":"smart_exp"}, {"options":"user_int"}, {"options":"blahblah"}]
for (var i = 0; i < json.length; i++){
alert(json[i].options)
}