Web Programming can be loosely defined as any programming activity that somehow is related to the Web. This opens up a wide range of programming environment, but strictly speaking in many cases these programming environments lie outside of the Web's core. However, some programming tasks are an integral part of the Web, for example scripting code and Asynchronous JavaScript and XML (AJAX), the ability of scripting code to request servers. Using some examples, this final part of the course explores the whole range of Web programming activities.
content providerfor delivering the representation
content provisionthemselves (SSI)
your daily news digest)
insert the file's modification date
mod_include
must be compiled into the serverOptions Includes
must be set to enable SSI processingAddType text/html .shtml AddHandler server-parsed .shtml
chmod +x
)XBitHack on
<!--#element attribute=value attribute=value ... -->
<!--#echo var="DATE_LOCAL" -->
<!--#echo var="LAST_MODIFIED" -->
<!--#config timefmt="%A %B %d, %Y" -->
<!--#include virtual="footer.shtml" -->
[an error occurred while processing this directive]
<!--#config errmsg="[ It appears that you don't know how to use SSI ]" -->
SSIErrorMsg "[ It appears that you don't know how to use SSI ]"
SSIErrorMsg "<!-- Error -->"
SetEnvIf
<!--#if expr="test_condition" --> <!--#elif expr="test_condition" --> <!--#else --> <!--#endif -->
<!--#include virtual="/cgi-bin/counter.pl" -->
<!--#exec cmd="dir" -->
IncludesNOEXEC
enables SSI but disables exec
being files
suEXEC
modereset
write once, run anywhere
java.applet.Applet
)javax.servlet.http.HttpServlet
for handling requests<pre onMouseOver="var input = document.createElement('input'); input.setAttribute('type', 'text'); parentNode.appendChild(input);"> ...
locally
XMLHttpRequest
API has been built for requesting XML via HTTP.php
or .asp
URIs)AddType application/x-httpd-php .php
Action application/x-httpd-php "/php/php.exe"
<?php ... ?>
is interpreted as PHP code<?php phpinfo(); ?>
<html> <head> <title>Get Request Headers</title> </head> <body> <table> <?php foreach ( $_SERVER as $index=>$value ) { if ( strpos($index, "HTTP_") === 0 ) { echo "<tr><th align='right' valign='top'>" . substr($index,5) . "</th><td>$value</td></tr>"; } } ?> </table> </body> </html>
(try shift-reload vs. no-shift-reload)
<html> <head> <title>Get Request Headers</title> </head> <body> <table> <?php foreach ( $_SERVER as $index=>$value ) { echo "<tr><th align='right' valign='top'>$index</th><td>$value</td></tr>"; } ?> </table> </body> </html>
(try adding a query string to the script's URI)
system
command<pre> <?php system("ls -lasg"); ?> </pre>
<pre> <?php system("ls -" . $_SERVER['QUERY_STRING']); ?> </pre>
system
as well<?php include("HttpClient.class.php"); $pageContent = HttpClient::quickGet('http://www.isnm.de/'); $highlightedContent = str_replace($_SERVER['QUERY_STRING'], "<span style='background-color : yellow'>" . $_SERVER['QUERY_STRING'] . "</span>", $pageContent); echo $highlightedContent; ?>
hen and eggproblem
replace="instance"
will only replace the instance (sequential editing)replace="none"
will not replace anything (sequential creation, multi-submit forms)<model><instance><data xmlns=""><accountnumber/><name/><address/></data></instance> <submission method="get" action=".../prefill" id="prefill" replace="instance"/> <submission method="put" action=".../change" id="change" replace="none"/> </model> ... <input ref="accountnumber"><label>Account Number</label></input> <submit submission="prefill"><label>Find</label></submit> <input ref="name"><label>Name</label></input> <textarea ref="address"><label>Address</label></textarea> <submit submission="change"><label>Submit</label></submit>
MM/DD/YY
or DD.MM.YY
or YYYY-MM-DD
are all not very user friendly5
and 05
represent the same value)hidethe model behind bindings and only use these for Controls
<xf:bind nodeset="/data/one" id="one" type="xs:integer" /> <xf:bind nodeset="/data/one" relevant="/data/two != 42" /> <xf:bind nodeset="/data/two" id="two" type="xs:integer" /> <xf:bind nodeset="/data/two" readonly="/data/one = 42" /> <xf:bind nodeset="/data/three" id="three" calculate="/data/one + /data/two" /> <xf:bind nodeset="/data/four" id="four" required="/data/three = 42" relevant="/data/three = 42" type="xs:date" constraint="starts-with(text(), '2007')"/>
<xf:input bind="one" incremental="true" /> <xf:input bind="two" incremental="true" /> <xf:input bind="three" incremental="true" /> <xf:input bind="four" incremental="true" />
<xf:secret bind="four" incremental="true" />
<xf:textarea bind="one" incremental="true" /> <xf:textarea bind="two" incremental="true" /> <xf:textarea bind="three" incremental="true" /> <xf:textarea bind="four" incremental="true" />
<xf:output bind="one" incremental="true" /> <xf:output bind="two" incremental="true" /> <xf:output bind="three" incremental="true" /> <xf:output bind="four" incremental="true" /> <xf:output bind="four" value="string-length(.)" incremental="true" />
<xf:upload ref="/data/five"> <xf:label>General Upload: </xf:label> <xf:filename ref="@filename"/> <xf:mediatype ref="@filename"/> </xf:upload> <xf:upload ref="/data/five" mediatype="image/*"> <xf:label>Image Upload: </xf:label> <xf:filename ref="@filename"/> <xf:mediatype ref="@filename"/> </xf:upload> <xf:upload ref="/data/five" mediatype="audio/*"> <xf:label>Audio Upload: </xf:label> <xf:filename ref="@filename"/> <xf:mediatype ref="@filename"/> </xf:upload>
<xf:range bind="one" start="0" end="10" incremental="true"><xf:label>0-10</xf:label></xf:range> <xf:range bind="one" start="0" end="50" incremental="true"><xf:label>0-50</xf:label></xf:range> <xf:range bind="one" start="0" end="100" step="10" incremental="true"><xf:label>0-100@10</xf:label></xf:range>
<xf:trigger bind="one"><xf:label>Button</xf:label></xf:trigger> <xf:trigger bind="six"><xf:label>Button42</xf:label></xf:trigger> <xf:submit submission="save"><xf:label>Save as...</xf:label></xf:submit>
open
<xf:select1 bind="one"> <xf:label>Default: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select1> <xf:select1 bind="one" appearance="full"> <xf:label>Full: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select1> <xf:select1 bind="one" appearance="compact"> <xf:label>Compact: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select1> <xf:select1 bind="one" appearance="minimal"> <xf:label>Minimal: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select1>
<xf:select bind="one"> <xf:label>Default: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select> <xf:select bind="one" appearance="full"> <xf:label>Full: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select> <xf:select bind="one" appearance="compact"> <xf:label>Compact: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select> <xf:select bind="one" appearance="minimal"> <xf:label>Minimal: </xf:label> <xf:item><xf:label>One</xf:label><xf:value>1</xf:value></xf:item> <xf:item><xf:label>Two</xf:label><xf:value>2</xf:value></xf:item> <xf:item><xf:label>Three</xf:label><xf:value>3</xf:value></xf:item> <xf:item><xf:label>Four</xf:label><xf:value>4</xf:value></xf:item> </xf:select>
<xf:textarea bind="data" incremental="true"> <xf:label>Your Message (characters remaining: <xf:output bind="length"/>)</xf:label> <xf:help>Enter the message text you wish to send as an SMS message.</xf:help> <xf:hint>Message text</xf:hint> <xf:alert>Additional characters will be truncated!</xf:alert> </xf:textarea>
on*
attributes in HTML<screen>0</screen> <screenbuffer>0</screenbuffer> <first>0</first> <second>0</second> <memory>0</memory> <result />
<xf:trigger> <xf:label>4</xf:label> <xf:action ev:event="DOMActivate"> <xf:setvalue ref="/equation/screenbuffer" value="/equation/screenbuffer * 10 + 4" /> <xf:setvalue ref="/equation/screen" value="/equation/screenbuffer" /> </xf:action> </xf:trigger>
<xf:trigger> <xf:label>+</xf:label> <xf:action ev:event="DOMActivate"> <xf:setvalue ref="/equation/first" value="/equation/screen" /> <xf:setvalue ref="/equation/screenbuffer" value="0" /> <xf:toggle ev:event="DOMActivate" case="add" /> </xf:action> </xf:trigger>
<xf:switch> <xf:case id="add"> <xf:trigger> <xf:label>=</xf:label> <xf:action ev:event="DOMActivate"> <xf:setvalue ref="/equation/second" value="/equation/screenbuffer" /> <xf:setvalue ref="/equation/result" value="/equation/first + /equation/second" /> <xf:setvalue ref="/equation/screen" value="/equation/result" /> <xf:setvalue ref="/equation/screenbuffer" value="0" /> </xf:action> </xf:trigger> </xf:case>