Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The "right" way to do synchronous HTTP request

You probably came here to chide me but this is a real use case.

In the world of online education, there are SCORM courses. I have to make old SCORM courses work on a site. SCORM courses are "web based" and run in a browser, but they expect to run in an iframe and they expect the parent to supply a GetValue method and a SetValue.

So these SCORM courses are doing things like parent.SetValue("score", "90") and moving on. That function is supposed to return "false" if there was any issue.

SCORM comes from the 90's, and in modern web we know we have to do callbacks/promises and http fails "often". You might think the solution is a SetValue that writes to local data and then tries and retries until it get's through, but the SCORM course typically is set up to only move to the next screen if the SetValue worked, so you shouldn't be letting the user advance unless the SetValue actually was saved on the server.

TL;DR

Assuming a syncronous request is a requirement, what is the right way to do it?

So far I know of $.ajax({async:false ... but now browsers warn about that and sound like they're going to just ignore your request to be synchronous. I am thinking maybe using websockets or web workers or something is the right way to do a syncronous request in modern programming. But I don't know how to make a request like that. And I am not allowed change the code of the SCORM courses (they are generated with various course-making tools)

To clarify, I have full control over the implementation of the SetValue function.

Will $.ajax({async:false ... work long term? (5-10 years)

NOTE: it is entirely acceptable in this use case to completely freeze the UI until the request either succeeds or fails. That's what the courses assume.

like image 929
AwokeKnowing Avatar asked Jun 01 '16 19:06

AwokeKnowing


People also ask

How is HTTP synchronous?

HTTP as a protocol is synchronous. You send a request, you wait for a response. As opposed to other protocols where you can send data in rapid succession over the same connection without waiting for a response to your previous data.

Is HTTP request synchronous or asynchronous?

XMLHttpRequest supports both synchronous and asynchronous communications. In general, however, asynchronous requests should be preferred to synchronous requests for performance reasons. Synchronous requests block the execution of code which causes "freezing" on the screen and an unresponsive user experience.

Which method is used by asynchronous HTTP request?

Ajax is the traditional way to make an asynchronous HTTP request. Data can be sent using the HTTP POST method and received using the HTTP GET method.


2 Answers

So far I know of $.ajax({async:false… but now browsers warn about that

This is the right way (if you're using jQuery), it sends a synchronous XMLHttpRequest. Just ignore the warning. It's a warning that you are using outdated technology, which you already know.

and sound like they're going to just ignore your request to be synchronous.

That's unlikely.

I am thinking maybe using websockets or web workers or something is the right way to do a syncronous request in modern programming.

No, websockets and web workers are always asynchronous, you can't use them to make your asynchronous request look synchronous (in fact there's nothing that lets you do this).

Will $.ajax({async:false… work long term? (5-10 years)

We cannot know (and SO is not a crystal ball). It might, especially in older browsers, or it might not. Browser vendors are reluctant to break compatibility of features that run the web, and synchronous requests still are needed from time to time. At some point, too few (important) web pages will use it (<1%, <1‰, whatever threshold they decide on) and browsers will finally be confident to remove it. At that point, your business will have realised to deprecate these outdated course-making tools.

like image 77
Bergi Avatar answered Sep 20 '22 10:09

Bergi


Based on my experience with learning management systems, the answer is: fake it.

You wrote:

it is entirely acceptable in this use case to completely freeze the UI until the request either succeeds or fails. That's what the courses assume.

Perhaps your courses assume this, but this is not the case in any learning management system I've used over the past decade.

From what I've seen, learning management systems don't use synchronous requests because they block other scripts, which gives the impression the page/course is locked up or broken. The workaround is to use async calls via an abstraction layer (which includes the SCORM API), and return 'true' to the course even if you have no way of verifying that the AJAX call was in fact was successful.

High-level view of how LMSs typically handle SCORM data:

When a course is launched, the LMS gets ALL of the course's existing SCORM data from the database, then puts it into a JavaScript object on the client side (accessible via the SCORM API). When you fetch data via SCORM, you are typically fetching data that is in this pre-loaded JS object -- you are NOT getting a real-time response directly from the database. Therefore AJAX is not needed when using SCORM's API.GetValue.

When you attempt to API.SetValue, you're initially storing the key/value pair in the JS object, not the SCORM database. Therefore the client-side JS object needs to synchronously indicate whether it successfully stored the data ('true') or not ('false'). The database -- and AJAX -- doesn't come into play until you try to persist the data to the database using API.Commit().

When you try to get a success value from API.Commit(), which is invoking AJAX, most LMSs will fake it. They will do an asynchronous request for the sake of ensuring the course doesn't feel broken, so the value returned from Commit() will almost always be 'true'. It's not reliable.

like image 27
pipwerks Avatar answered Sep 22 '22 10:09

pipwerks