This is a quick intro to building a dynamic web page that uses modern JavaScript to talk to a Lua Server Page (LSP). We use the Fetch API with async/await to send URL-encoded data and to receive JSON data.
If you're looking for a deeper dive into AJAX in general, check out the full AJAX tutorial and online interactive AJAX tutorials.
An Ajax web application retrieves data from the server asynchronously in the background without interfering with the display and behavior of the existing page. Ajax applications are typically designed for enhancing standard web-applications and are designed to gracefully degrade to a standard web application when the browser does not support JavaScript or if JavaScript is disabled.
In the following example, a basic calculator is designed as a standard web application, and we will later enhance this calculator by using Ajax. To keep it simple, the calculator will be designed to add two numbers only.
<?lsp local var1 local var2 local result = "" -- Fetch all URL encoded (POST'ed form) data sent from client as a Lua table. local d = request:data() if d.var1 and d.var2 then -- If client sends data -- Convert URL encoded data to numbers var1 = tonumber(d.var1) var2 = tonumber(d.var2) -- var1 and/or var2 are nil if data could not be converted to a number. -- Set result = var1+var2 if var1 and var2 are OK, otherwise set result to -- "???" result = var1 and var2 and (var1+var2) or "???" end -- Else, a standard browser GET ?> <html> <head> <title>Addition</title> </head> <body> <form method="post"> <input type="text" name="var1" value="<?lsp=var1 or ""?>"/> + <input type="text" name="var2" value="<?lsp=var2 or ""?>"/> = <span id="result"><?lsp=result?></span> <br/> <input type="submit" value="Submit"/> </form> </body> </html>
The html form starts on line 26 and ends on line 33. The user enters a number into the two text fields (line 27 and 29). The data is sent as URL encoded data to the server when the user presses the submit button on line 32. The URL-encoded data for the above form is sent as: var1=10&var2=11, where 10 and 11 are numbers entered into the text fields.
Lua script code starting on line 1 and ending on line 20 is executed by the server every time the browser sends a request to the LSP page. If the browser sends the two URL-encoded variables var1 and var2, line 9 to 17 in the above code is executed on the server. The server side code extracts the variables and converts the variables to numbers.
The "result" is dynamically inserted into the generated HTML on line 30. We also update the value attributes on line 27 and 29. Updating the value fields make the input variables persistent -- i.e. the HTML code returned in response to a "browser POST request" have the text fields set to the previous value.
Lets's go ahead and enhance the web-application using Ajax, but at the same time, make sure the application still works when JavaScript is disabled in the browser.
<?lsp local var1 local var2 local result = "" -- Fetch URL-encoded form data (GET or POST) local d = request:data() if d.var1 and d.var2 then var1 = tonumber(d.var1) var2 = tonumber(d.var2) result = var1 and var2 and (var1 + var2) or "???" -- Handle AJAX request if "true" == request:header"X-AJAX" then trace"AJAX call" response:json{result = result} -- does not return end trace"Standard POST" end ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lua Server Pages - AJAX Example</title> <script> async function calculateAsync() { const var1 = document.getElementById("var1").value; const var2 = document.getElementById("var2").value; const formData = new URLSearchParams(); formData.append("var1", var1); formData.append("var2", var2); try { const response = await fetch("index.lsp", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "X-AJAX": "true" }, body: formData }); if (!response.ok) throw new Error("Network response was not OK"); const data = await response.json(); document.getElementById("result").textContent = data.result; } catch (error) { console.error("Error:", error); document.getElementById("result").textContent = "???"; } } </script> </head> <body> <h1>Lua Server Pages - AJAX Example</h1> <form action="index.lsp" method="post"> <input id="var1" name="var1" type="text" value="<?lsp= var1 or "" ?>" /> + <input id="var2" name="var2" type="text" value="<?lsp= var2 or "" ?>" /> = <span id="result"><?lsp= result ?></span> <br><br> <input type="submit" value="Standard POST" /> <input type="button" value="AJAX" onclick="calculateAsync()" /> </form> </body> </html>
RESTful web-services can easily be designed using the directory type. The getting started guide includes an example of how one can create RESTful web-services and use logical URL's.