Slide Set 5 1
Ajax
- Asynchronous JavaScript and XML
- Combination of JavaScript, CSS, XHTML,
XML, and the XMLHttpRequest object to dynamically modify a portion of a web page using data from the server
- Goal is to make web applications look and “feel”
Ajax Asynchronous JavaScript and XML Combination of JavaScript, - - PowerPoint PPT Presentation
Ajax Asynchronous JavaScript and XML Combination of JavaScript, CSS, XHTML, XML, and the XMLHttpRequest object to dynamically modify a portion of a web page using data from the server Goal is to make web applications look and
Slide Set 5 1
Slide Set 5 2
http://www.google.com/webhp?complete=1&hl=en Compare this to www.google.com where you'll see a page refresh when google returns with search results
Slide Set 5 3
Slide Set 5 4
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxgetmsg1.html
Slide Set 5 5
var XMLHttpRequestObject = false; if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else if (window.ActiveXObject) //IE way to create object XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); else alert("Ajax not supported"); function getData(dataSource, divID) { var obj = document.getElementById(divID);
if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", dataSource); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)
} XMLHttpRequestObject.send(null); } else
}
Slide Set 5 6
Slide Set 5 7
Slide Set 5 8
Slide Set 5 9
Slide Set 5 10
Slide Set 5 11
Slide Set 5 12
Slide Set 5 13
Slide Set 5 14
Slide Set 5 15
Slide Set 5 16
Slide Set 5 17
Slide Set 5 18
Slide Set 5 19
– create the normal version with Microsoft.XMLHTTP
– more recent versions available: Msxml2.XMLHTTP,
Slide Set 5 20
window.onload = getXMLHttpRequest; var XMLHttpRequestObject = false; function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else { try { XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); } } } } http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxgetmsg2.html
Slide Set 5 21
22
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp1.html
Slide Set 5 23
http://www.servername.com/path/script.php?a=10&b=32&c=hello+there
Slide Set 5 24
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp2.html
Slide Set 5 25
Slide Set 5 26
– change the PHP code so that it accesses POST array
– change the XMLHttpRequest object open to do a POST
– call the setRequestHeader method of the
– send the data to the server using the XMLHttpRequest
Slide Set 5 27
var XMLHttpRequestObject = false; if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else if (window.ActiveXObject) //IE way to create object XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); else alert("Ajax not supported"); function getData(dataSource, divID, data) { var obj = document.getElementById(divID);
if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)
} XMLHttpRequestObject.send("data=" + data); } else
}
Slide Set 5 28
<body> <form action=""> <p> <input type="button" value="Fetch message 1"
<input type="button" value="Fetch message 2"
</p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div> </body>
Slide Set 5 29
Example at: http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxphp3.html
Slide Set 5 30
XMLHttpRequestObject.overrideMimeType(“text/xml”);
xmlDocument = XMLHttpRequestObject.responseXML;
Slide Set 5 31
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml1.html
Slide Set 5 32
Slide Set 5 33
window.onload = initialize; function initialize() { getXMLHttpRequest(); //reset form to the selected item var obj = document.getElementById("myform");
} function getSelect() { var obj = document.getElementById("states"); if (obj.value == "Maryland") getData("maryland.xml"); else if (obj.value == "North Carolina") getData("northcarolina.xml"); }
Slide Set 5 34
var XMLHttpRequestObject = false; function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object XMLHttpRequestObject = new XMLHttpRequest(); else { try { XMLHttpRequestObject = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); } } } }
Slide Set 5 35
function getData(dataSource) { if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", dataSource); //need this to make Firefox treat the returned data //as xml XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send(null); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 36
function buildSelect(xml) { //get array of city nodes from XML var cities = xml.getElementsByTagName("city"); //get select element from HTML document var select = document.getElementById("cities"); for (var i = 0; i < cities.length; i++) { //first child of the cities node is a text node select.options[i] = new Option(cities[i].firstChild.data); } }
Slide Set 5 37
<body> <form id="myform" action=""> <p> <select size="1" id="states"> <option value="">Select a State</option> <option value="Maryland">Maryland</option> <option value="North Carolina">North Carolina</option> </select> </p> <p> <select size="1" id="cities"> </select> </p> </form> <div id ="errmsg"> </div> </body>
Slide Set 5 38
http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml2.html
Slide Set 5 39
Slide Set 5 40
<?php extract($_POST); echo '<?xml version="1.0" ?><cities>'; getData($data); echo '</cities>';
Slide Set 5 41
function getData($state) { $file = fopen("states.txt", "r") or exit("Unable to open file"); $done = false; //remove backslashes (magic quotes) and quotes $state = stripslashes($state); $state = str_replace("'", "", $state); $state = str_replace('"', "", $state); $state = $state.":\n"; while ($done == false && !feof($file)) { $line = fgets($file); if (strcmp($line, $state) == 0) { $line = fgets($file); do { echo '<city>'.$line.'</city>'; $line = fgets($file); } while (!feof($file) && strpos($line, ':') === false); $done = true; } } } ?>
Slide Set 5 42
function getSelect() { var obj = document.getElementById("states"); if (obj.value == "Maryland") getData("ajaxxml2.php", "Maryland"); else if (obj.value == "North Carolina") getData("ajaxxml2.php", "North Carolina"); }
Slide Set 5 43
function getData(dataSource, data) { if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //post header required //need this to make Firefox treat the file as an xml file XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 44
– in earlier examples, only one XMLHttpRequest
– this one object would be modified by both requests
– multiple XMLHttpRequest objects
Slide Set 5 45
– every time an outer function is called, a new copy of
– inner functions have access to outer function local
Slide Set 5 46
function getData(dataSource, data) { //create new XMLHttpRequest object var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //need this to make Firefox treat the file as an xml file XMLHttpRequestObject.overrideMimeType("text/xml"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { buildSelect(XMLHttpRequestObject.responseXML); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; } http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxxml3.html
Slide Set 5 47
– function call – or, JavaScript object
Slide Set 5 48
window.onload = initialize; function initialize() { //reset form to the selected item var obj = document.getElementById("mydiv");
} function getData() { //create new XMLHttpRequest object var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("GET", "ajaxjs1.php"); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { //eval evaluates the text as JavaScript code eval(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send(null); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 49
function greeting() { var obj = document.getElementById("mydiv");
} <?php echo "greeting();" ?> http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxjs1.html
Slide Set 5 50
Use PHP to create a string representing a JavaScript object <?php $text = "{function: 'greeting', operand: 'CS 5530'};"; echo $text; ?> Use eval to create the JavaScript object var object; eval('object = ' + XMLHttpRequestObject.responseText); Use eval to invoke the method specified by the object with its parameter(s) eval(object.function + '("' + object.operand + '");'); http://www.cs.appstate.edu/~can/classes/5530/set5/ajaxjs2.html
Slide Set 5 51
Slide Set 5 52
Slide Set 5 53
<?php $data = urlencode($_GET["qu"]); $file = fopen("http://www.google.com/complete/search?h1=en&js=true&qu=". $data, "r"); while (!feof($file)) { $line = fgets($file); echo $line; } ?> Notice that the qu parameter for google suggest comes from my web document. URLs in PHP are opened and read from just like files. http://www.cs.appstate.edu/~can/classes/5530/set5/google.php
Slide Set 5 54
http://www.cs.appstate.edu/~can/classes/5530/set5/google.php?qu='Mary'
window.google.ac.Suggest_apply(frameElement, "\\\x27Mary\\\x27", new Array(2, "mary kay", "3,460,000 results", "mary poppins", "2,560,000 results", "mary louise parker", "2,160,000 results", "mary j blige", "2,880,000 results", "mary elizabeth winstead", "589,000 results", "mary kate olsen", "2,570,000 results", "mary kate and ashley", "3,020,000 results", "mary winkler", "1,780,000 results", "mary kay cosmetics", "1,140,000 results", "mary queen of scots", "1,470,000 results"), new Array(""));
Slide Set 5 55
– Browser has already visited URL once and stored
– Rather than visiting the PHP script again, browser
– Of course, this is bad if you are the developer and
Slide Set 5 56
XMLHttpRequestObject.open("GET", “script.php?d=' + new Date().getTime());
Slide Set 5 57
Slide Set 5 58
Slide Set 5 59
Slide Set 5 60
– majax_get – majax_post
61
<script type="text/javascript" src="majax-0.1.1/majax.js"></script> <script type="text/javascript" > //<![CDATA[ function getData(dataSource) { //pass the url to majax get majax_get(dataSource, null); } function handler() { var div=document.getElementById("targetDiv"); div.innerHTML = MAJAX_RESPONSE; } //register the XMLHttpRequest done handler MAJAXCM_COMPLETE.register(handler); //]]> </script> </head> <body> <form action=""> <p><input type="button" value="Fetch the message" onclick = "getData('msg.txt')" /></p> </form> <div id="targetDiv"> <p>Fetched message will appear here.</p> </div>
http://www.cs.appstate.edu/~can/classes/5530/set5/majaxgetmsg1.html
62
<script type="text/javascript" src="majax-0.1.1/majax.js"></script> <script type="text/javascript" > //<![CDATA[ function getData(dataSource, data) { //pass the url to majax get majax_post(dataSource, "str="+data); } function handler() { var div=document.getElementById("targetDiv"); div.innerHTML = MAJAX_RESPONSE; } //register the XMLHttpRequest done handler MAJAXCM_COMPLETE.register(handler); //]]> </script> </head> <body> <form action=""> <p> <input type="button" value="Fetch the message" onclick = "getData('majaxgetmsg2.php', 'CS 5530')" /></p> </form> <div id="targetDiv"><p>Fetched message will appear here.</p></div>
http://www.cs.appstate.edu/~can/classes/5530/set5/majaxgetmsg2.html
Slide Set 5 63
– Dojo core – Dijit – widget system – DojoX – incubator area for Dojo (works in progress)
Slide Set 5 64
– URL – callback function – error function – what type of response to receive from server (XML,
– form for posted data
Slide Set 5 65
{ url: "file.txt", handleAs: "text", timeout: 5000, load: function(response, ioArgs) { dojo.byId("cargo").innerHTML = response; return response; }, error: function(response, ioArgs) { console.error("HTTP status code: ", ioArgs.xhr.status); return response; } }
Slide Set 5 66
<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.9.0/dojo/dojo.xd.js"></script> <script type="text/javascript"> //<![CDATA[ function hello() { dojo.xhrGet( { //The following URL must match that used to test the server. url: "http://www.cs.appstate.edu/~can/classes/5530/set5/msg.txt", handleAs: "text", timeout: 5000, // Time in milliseconds // The LOAD function will be called on a successful response. load: function(response, ioArgs) { dojo.byId("cargo").innerHTML = response; return response; }, error: function(response, ioArgs) { console.error("HTTP status code: ", ioArgs.xhr.status); return response; } }); } //]]> </script>
Slide Set 5 67
<script type="text/javascript"> //<![CDATA[ dojo.addOnLoad(hello); //]]> </script> </head> <body> <div id="cargo" style="font-size: big"></div> <!--.--> </body> </html> http://www.cs.appstate.edu/~can/classes/5530/set5/dojohello1.html Welcome to Ajax! http://www.cs.appstate.edu/~can/classes/5530/set5/msg.txt
Slide Set 5 68
url: "http://www.cs.appstate.edu/~can/classes/5530/set5/dojohello2.php?str='CS 5530'",
Slide Set 5 69
Slide Set 5 70
Slide Set 5 71
Slide Set 5 72
Slide Set 5 73
– sajax_init(); //sets up Sajax – sajax_export(“function”); //makes a server-side
– sajax_handle_client_request(); //connects server-
– sajax_show_javascript(); //generates the
Slide Set 5 74
<? require("sajax-0.12/php/Sajax.php"); // The server code that does the work. function adder($operand1, $operand2) { return $operand1 + $operand2; } sajax_init(); sajax_export("adder"); sajax_handle_client_request(); ?>
Slide Set 5 75
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Sajax Example</title> <script type="text/javascript"> //<![CDATA[ <? sajax_show_javascript(); ?> function do_adder() { var operand1, operand2;
x_adder(operand1, operand2, show_results); } function show_results(result) { document.getElementById("result").value = result; } //]]> </script> </head>
Slide Set 5 76
<body> <h1>Sajax Example</h1> <p> <input type="text" name="operand1" id="operand1" value="4" size="3" /> + <input type="text" name="operand2" id="operand2" value="5" size="3" /> = <input type="text" name="result" id="result" value="" size="3" /> <input type="button" name="check" value="Add" onclick="do_adder(); return false; /> </p> </body> </html> http://www.cs.appstate.edu/~can/classes/5530/set5/sajax1.php
Slide Set 5 77
Slide Set 5 78
Slide Set 5 79
window.onload = initialize; function initialize() { var obj = document.getElementById("Dog");
var obj = document.getElementById("Cat");
}
function getImage() { var obj = document.getElementById("Dog"); if (obj == this) getData("downloadimage.php", "Dog"); var obj = document.getElementById("Cat"); if (obj == this) getData("downloadimage.php", "Cat"); }
Slide Set 5 80
function getXMLHttpRequest() { if (window.XMLHttpRequest) //Firefox way to create object return new XMLHttpRequest(); else { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Ajax not supported"); return null; } } } }
Slide Set 5 81
function getData(dataSource, data) { //create new XMLHttpRequest object var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { displayImage(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; } function displayImage(imageName) {
}
Slide Set 5 82
<body> <form id="myform" action=""> <p> <input type="button" id="Dog" value="Show Dog Image" /> <input type="button" id="Cat" value="Show Cat Image" /> </p> </form> <div id ="imageLoc"> </div> </body> http://www.cs.appstate.edu/~can/classes/5530/set5/downloadimage.html
Slide Set 5 83
<?php extract($_POST); getData($data); function getData($image) { //remove backslashes (magic quotes) and quotes $image = stripslashes($image); $image = str_replace("'", "", $image); $image = str_replace('"', "", $image); if (strcmp($image, "Dog") == 0) echo "dog.jpg"; else if (strcmp($image, "Cat") == 0) echo "cat.jpg"; else echo $image." not found"; } ?>
Slide Set 5 84
Slide Set 5 85
– timeoutSet – initially false; set to true if a timeout
– downloadOK – initially false; set to true if successful
Slide Set 5 86
function getImage() { var obj = document.getElementById("Dog"); //deliberately mis-name php script to see my timeout alert if (obj == this) getData("downloadimag.php", "Dog"); var obj = document.getElementById("Cat"); if (obj == this) getData("downloadimage.php", "Cat"); } http://www.cs.appstate.edu/~can/classes/5530/set5/timeout.html
87
function getData(dataSource, data) { var XMLHttpRequestObject = getXMLHttpRequest(); if (XMLHttpRequestObject) { XMLHttpRequestObject.open("POST", dataSource); XMLHttpRequestObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); var timeoutSet = false; var downloadOK = false; XMLHttpRequestObject.onreadystatechange = function() { if (XMLHttpRequestObject.readyState == 1 && timeoutSet == false) { window.setTimeout( function() { if (!downloadOK) { alert("Sorry, time out."); XMLHttpRequestObject.abort(); } }, 1000); //call function literal in 1000 milliseconds timeoutSet = true; } if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) { downloadOK = true; displayImage(XMLHttpRequestObject.responseText); } } XMLHttpRequestObject.send("data="+data); } else document.getElementById("errmsg").innerHTML = "Ajax not supported"; }
Slide Set 5 88
– well-formedness – legal tags and nesting – validity –
Slide Set 5 89
Slide Set 5 90
Slide Set 5 91
<?xml version="1.0"?> <!DOCTYPE name [ <!ELEMENT name (first, last) > <!ELEMENT first (#PCDATA) > <!ELEMENT last (#PCDATA) > <!ENTITY mr "Mister"> ]> <name> <first>&mr; Jack</first> <last>Sprat</last> </name> http://www.cs.appstate.edu/~can/classes/5530/set5/name.xml
Slide Set 5 92
handleXML(XMLHttpRequestObject.responseXML); function handleXML(xml) { var XMLstr = new stringTree(); XMLstr.traverse(0, xml); var obj = document.getElementById("mydiv1"); displayData(obj, "<h2>XML document</h2>" + XMLstr.str); }
93
function stringTree() { this.str = ""; this.traverse = function traverse(level, node) { this.str = this.str + "Level: " + level + ", Node Name: " + node.nodeName + ", Node Type: " + node.nodeType + ", Node Value: " + node.nodeValue; if (node.hasChildNodes()) { this.str = this.str + " { "; var children = node.childNodes; for (var i = 0; i < children.length; i++) this.str = this.str + children[i].nodeName + " "; this.str = this.str + " }\n"; //visit the next level for (var i = 0; i < children.length; i++) this.traverse(level + 1, children[i]) } else this.str = this.str + "\n"; } } Of course, this is just like our JavaScript to traverse an XHTML document. http://www.cs.appstate.edu/~can/classes/5530/set5/name.html
94
– Firefox creates nodes for this whitespace; IE does
Slide Set 5 95
function removeWhiteSpace(xml) { var i; for (i = 0; i < xml.childNodes.length; i++) { var currentNode = xml.childNodes[i]; if (currentNode.nodeType == 1) { //element node removeWhiteSpace(currentNode); } if (((/^\s+$/.test(currentNode.nodeValue))) && (currentNode.nodeType == 3)) { //empty text node xml.removeChild(xml.childNodes[i--]); } } } http://www.cs.appstate.edu/~can/classes/5530/set5/name2.html
Slide Set 5 96
Slide Set 5 97
<?xml version="1.0"?> <events> <event type="Food"> <event_title>Cookie Dough Fundraiser</event_title> <committee> <member role="chair">Jane Doe</member> <member role="secretary">Jack Sprat</member> <member role="at large">Carol Smith</member> </committee> </event> <event type="Fair"> <event_title>Fall Festival Fundraiser</event_title> <committee> <member role="chair">Sally Chair</member> <member role="secretary">John Helper</member> <member role="at large">Carol Smith</member> </committee> </event> <event type="Food"> <event_title>Donut Sale</event_title> <committee> <member role="chair">Ruth Member</member> <member role="secretary">Eric Serve</member> <member role="at large">Connie Adams</member> <member role="at large">Henry Assistant</member> </committee> </event> </events>
98
function handleXML(xml) { var titles = xml.getElementsByTagName("event_title"); var committees = xml.getElementsByTagName("committee"); var i = 0; var j = 0; var table = document.createElement("table"); table.border = "5px"; var row = table.insertRow(-1); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); cell1.innerHTML = "<b>Event</b>"; cell2.innerHTML = "<b>Chair</b>"; for (i = 0; i < titles.length; i++) { var members = committees[i].getElementsByTagName("member"); for (j = 0; j < members.length; j++) { var attributes = members[j].attributes; if (attributes.getNamedItem("role").nodeValue == "chair") var chair = members[j].firstChild.nodeValue; } row = table.insertRow(-1); cell1 = row.insertCell(0); cell2 = row.insertCell(1); cell1.innerHTML = titles[i].firstChild.nodeValue; cell2.innerHTML = chair; } document.getElementById("mydiv").appendChild(table); } Builds table of fundraising events and the chairs http://www.cs.appstate.edu/~can/classes/5530/set5/fundraising.html
Slide Set 5 99
Slide Set 5 100
<script type=”text/javascript”>window.location=www.malicious.com</script>
– one solution to this problem is to convert sensitive
Slide Set 5 101
– solution is to simply do bounds checking
– do it yourself (ask user for a password) – server-side authentication – users automatically