As a follow up to my post, Getting Started with Javascript, this time we will take a look at extending the functionality of FileMaker by providing a means to submit to a url using the POST method by utilizing AJAX.
What is POST?
POST is a http method of submitting information to a web server. There are several others that exist, but GET and POST are the most common. These are specified in an HTML form as an attribute of the “form” element.
The main difference between these two methods are that GET will submit all data as part of the URL, whereas POST will enclose the data as part of the message body instead of the location. Using POST, you can get arbitrarily large amounts of data submitted without relying on the URI string length.
What is AJAX?
AJAX stands for Asynchronous Javascript and XML. Despite the name, the use of XML is not required. Some time in the 90s, microsoft introduced support for something called XMLHttpRequest, or XHR. This is the object used by javascript to request and return information within a web page without reloading the entire page.
For our purposes, the asynchronous aspect is important to us. As opposed to other methods for getting data back from a web script, this allows us to continue working while the script works in the background.
Why do this at all?
FileMaker 13 introduced some support for using this request method (via httppost) with the “Insert from URL” script step. I say “some” support because you have no control over setting http headers or other attributes as part of the request. Some third party web services may require specific headers be set in order for them to work properly.
Using Javascript to handle our request allows us to control setting the HTTP header as well as submitting the content in other formats, such as JSON or XML, instead of the commonly used key/value pairs that get submitted as text.
Furthermore, this method does not use any plugins, so will also work in FileMaker Go. It may also work in WebDirect, however the method we use for returning information via a FMP url will not work in WebDirect, but could use some custom web publishing to get similar functionality.
How this example works…
In the example file, we use some rather straightforward Javascript (no jquery or other dependencies) to create our request and return whatever response we get as a result, and log that in our database. By substituting in our values into the HTML used to perform the request, we can easily reuse this code for lots of different purposes.
You can use RequestBin (http://requestb.in/) to create a URL that you can use in the example file in order to inspect how the HTTP request is received by the web server. Put the URL in the “Form Action” field in the sample database in order to get started.
We have three records in this example, to demonstrate three different types of data we will send as the payload. First is the familiar key/value pair query string, with the content set to text/html. The other two will send JSON and XML as the entire POST request, with no other parameters. That will make up the entirety of the request. To do so, we will select the appropriate Content Type for the data we are submitting, “application/json” and “text/xml” respectively.
The values we set in our fields get substituted into the necessary javascript via our script, and we use a web viewer to render our HTML and run the javascript. Since there is no HTML returned that we need to look at, this can be performed in a web viewer that is off to the right of the visible portion of our layout. What we care about is the javascript doing the work and handing the result back to FileMaker.
Our script sets the necessary HTML javascript and run in our web viewer, then we will wait for a result. If the AJAX code gets a response, an FMP URL is called that references the current file and triggers a script to hand off the response and write it to a field. Since there is always a possibility the server is unreachable, we can handle how long we wait for a response with by installing an OnTimer Script.
In my example file, I set the first OnTimer script to 3 seconds, and if we have not gotten a response back yet, that script will open a popover to prevent the user from changing anything while we wait and install another OnTimer Script to run in an additional 27 seconds (30 seconds total).
So if after 30 seconds, we have not gotten a response from our web server, we close the popover, log that we got no response, and uninstall the OnTimer Script. If we DO get a response, we log the response and also uninstall any OnTimer Script.
PUT and DELETE Methods
In addition to GET and POST methods when submitting information, there are several other methods that are supported and sometimes required by certain web services. Among those are PUT and DELETE, which are typically used by RESTful web services to update or change the state of a resource and remove or delete a resource, respectively.
These work just like POST, where the payload is sent in the body of the request. The difference is how the request is received on the server where the different methods will serve to inform the server side script.
As with all other examples using POST or GET, you will want to test with the server or service you are working with to make sure all works as expected. This example is meant to be a starting point for leveraging javascript to extend the capabilities of your desktop or mobile application.
Example File
You can get the example file from it’s GitHub page:
Note: Click the “Download Zip” link at the bottom of the right hand column of the GitHub page.
Additionally…Of CORS
Since AJAX is javascript that runs in client’s browser, there are security concerns regarding cross site scripting. This has to do with scripting in a page that reaches out to a different domain to execute code in the same page.
Cross-Origin Resource Sharing (CORS) is a W3C spec that allows scripting communication across domains. CORS is supported in modern browsers, and also in the web viewer that FileMaker uses. There are sites offering web services that support making calls with AJAX and others that might not.
If you have a PHP script that you would like to enable CORS on, you can add the following code snippet to the top.
// enable cors
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
And as always, test, test, test.
References
- AJAX Programming – Wikipedia.org
- GET vs. POST – w3Schools
- FileMaker 13: Getting Started with Javascript – Soliant Blog
Nice post, Mike. Very useful!
Thank you for sharing.
Pingback: FileMakerとJavascript:AJAX POST | Not Only FileMaker
Great tutorial and it worked first time on my Mac.
However I could not get it to work on Filemaker Go V13 and V14 on my iPad 9.1(13B143)
Hi Mike,
I cant download the sample file, could you help please
The sample file is hosted on GitHub here: https://github.com/SoliantMike/FM-AJAXPOST
Look for the “Download Zip” button to get all the files.
Nice tool !
Is there a way to use it to POST an XML request to my Web Service so it can execute a function and return the result to Filemaker ?
I tried but don’t get any response from the web service…
Hi Anthony,
I guess that depends on your web service. If it is something you developed, you can have it do whatever you like. Otherwise, you may be constrained to the functionality of that particular service. If you do not get a response, it’s likely a CORS issue.
Mike
Hi Mike,
Yes, it is a web service that I developed and will always be at localhost. If its a CORS issue, does that mean that I have no way of making it work with the FileMaker WebViewer ?
Thanks,
Anthony
At the end of the blog post, I show an example of the settings to enable CORS access in PHP by setting the needed http headers. Do those help?
Hi Mike. Thank you so much for this technique. It works great in FileMaker Pro. But it’s not working in Web Direct. Can you think of why that might be?
Hi Jeff,
This will only work in Pro and Go as it is written, since it depends on the FMP URL to get the data returned to the client. You could always use a little CWP to pass the result back to the server and get it working with WebDirect as well.
Mike
Hi Mike,
Great post!
I am looking into creating a standalone FileMaker Go 15 solution that can post some data to a local web service ( JSON data with custom headers ). The Webservice is out POS system.
Because i have no Filemaker Server or even Pro on premise I cannot use plugins like MBS or BaseElements.
This post seemed to be Just what I needed to continue with this product. BUT, unfortunately I am running blancs here. This sollution works perfect on FileMaker Go 14, but not on FileMaker Go 15.
I Believe it’s due to this : LINK : http://help.filemaker.com/app/answers/detail/a_id/15999
on the bottom:
“If the web viewer has embedded HTML that includes file references, the web viewer will appear to be empty in FileMaker Go 15. Instead, create an HTML file and save it along with any related files in the Temporary folder. Then, change the web viewer to reference the HTML file.”
So i Adapted you file a little to play around with it.
Set Variable [ $HTMLFile; Value: Get ( TemporaryPath ) & “PostField.html” ]
Set Variable [ $output; Value: “file:” & $HTMLFile ]
Export Field Contents [ Requests::post field; “$output” ]
Set Web Viewer [ Object Name: “Web” ; URL: $output” ]
I can find the file in my TemporaryPath and open it with Chrome or Safari, and the post is sent, but for some reason the post is not send by the WebViewer.
No idea what i am doing wrong here…
There are no assets saved outside of the file, so that kb article doesn’t apply. I am able to replicate the error, which seems to have to do with FM 15 and possibly iOS 10 safari handling minified data url with javascript. I will try to find time to update it.
In the meantime, you can always write a fairly simple PHP script that could take your request and relay to the final endpoint. That php script can be made more friendly to the FM insert from URL script, so could still work from Go with supported script steps. Would that work in the interim at least?
Hi Mike, a PHP script would probably be great also, but i have no knowledge of php or javascript at that. i must say that the javascript you provided is fairly simple to read…
Hi Mike, thanks so much for the demo: it works perfectly using POST method but not with GET and I don’t understand why.
I believe if you are using GET, you can just use the insert from URL script step, right?