Receive 102 http status in XMLHttpRequest - javascript

Node.js supports sending a 102 Processing status code since v10, but I'm not sure how this can be used.
Is it something the browser only uses internally (like it delays the timeout event) or can we access this temporary status in any way?
I'd like to let my javascript code know "hey, I'm working on this, sit tight". Sending a temporary status seems like the easiest way out.
Another option is to work with a 202 status, but that requires a lot more changes.

You are right.
102 PROCESSING
An interim response used to inform the client that the server has accepted the complete request, but has not yet completed it.
This status code SHOULD only be sent when the server has a reasonable expectation that the request will take significant time to complete. As guidance, if a method is taking longer than 20 seconds (a reasonable, but arbitrary value) to process the server SHOULD return a 102 (Processing) response. The server MUST send a final response after the request has been completed.
Methods can potentially take a long period of time to process, especially methods that support the Depth header. In such cases the client may time-out the connection while waiting for a response. To prevent this the server may return a 102 Processing status code to indicate to the client that the server is still processing the method.
You can see it at https://httpstatuses.com/102 or https://www.rfc-editor.org/rfc/rfc2518#section-10.1

Related

Prevent duplicate HTTP requests for cachable responses

Is it possible (without an application layer cache of requests) to prevent sending an HTTP request for the same resource multiple times when it's cachable? And if yes, how?
E.g. instead of
at time 0: GET /data (request#1)
at time 1: GET /data (request#2)
at time 2: received response#1 for request#1 // headers indicate that the response can be cached
at time 3: received response#2 for request#2 // headers indicate that the response can be cached
 
at time 0: GET /data (request#1)
at time 1: GET /data (will wait for the response of request#1)
at time 2: received response#1 for request#1 // headers indicate that the response can be cached
at time 3: returns response#1 for request#2
This would require that its possible to indicate to the browser that the response will be cachable before the response headers are read. I am asking if there is such a mechanism. E.g. with a preceding OPTIONS or HEAD request of some kind.
My questions is, if there is a mechanism to signal the browser that the response for URI will be cachable
Yes this is what the Cache-control headers do.
and any subsequent requests for that URI can return the response of any in-flight request....Ideally this would be part of the HTTP spec
No HTTP does not do this for you, you need to implement the caching yourself. This is what browsers do.
I did want to check if there is already something ready ouf-of-the-box
Javascript libraries don't typically honour caching, as a AJAX request is usually for data and any caching of data usually happens on the server. I don't know any library and of course asking for Js libraries is out of scope on SO.
Depending on the browser the second request could be stalled and served if cachable, e.g. in Chromium for non range requests:
The cache implements a single writer - multiple reader lock so that only one network request for the same resource is in flight at any given time.
https://www.chromium.org/developers/design-documents/network-stack/http-cache
Here an example where three concurrent requests result in only a single server call:
fetch('/data.json').then(async r => console.log(await r.json()));
fetch('/data.json').then(async r => console.log(await r.json()));;
setTimeout(() => fetch('/data.json').then(async r => console.log(await r.json())), 2000);
The subsequent request have 0B transferred and have the same random number, showing that only a single server call was made.
This behavior is not the same for e.g. Firefox:
An interesting question that comes to mind is what would happen when a request for a resource is made while a H2 push for that resource was initiated before but not yet finished.
For reproducing here the test code:
https://gist.github.com/nickrussler/cd74ac1c07884938b205556030414d34

Why does curl terminate an http request to my server early when an early response is received, but http requests from my browser frontend don't?

I have a https route in my API server that accepts file uploads. There's some validation for the uploads and if, for example, one of the query parameters is invalid the server rejects the upload before consuming the entire request body (which can be really huge).
When I run a request against this API with curl (or from Insomnia, which I think just uses curl under the hood), and the server returns a response before consuming the entire body, curl terminates without continuing to upload data even though it has not sent the entire payload yet.
The curl command:
curl --request POST \
--url 'https://api.example.com/v0/projects/38/media?filename=somethingInvalid' \
--header 'content-type: video/mp4' \
--cookie session=orMaybeIAmInvalid \
--data '<gigantic chunk of binary here>'
This terminates in under a second, and the server returns 400 with some response like your stuff is wrong yo. However, if the query parameter is valid, the upload takes about 5 minutes. So this is all working as intended: I don't want to make the user wait minutes and minutes for the 400 that's not based on the file's contents at all.
The same request has the opposite behaviour from my frontend web application. If I run an xmlhttprequest request with the same configuration, even if the web server has reached the point where it is trying to return 400 and no longer cares about the request body being uploaded, the browser keeps chugging along for 5 minutes before even parsing that it has received 400. Why is that?
I say "where it is trying to return 400" because I'm not exactly sure how the underlying technologies work here. I have, in my web server which is built in play framework, this line that's just returning 400:
if (stuff.isInvalid()) {
return completedFuture(badRequest("your stuff is wrong yo"));
}
But, come to think of it, I'm actually pretty surprised that this works at all with curl given that the request body has not been entirely consumed at this point. So as much as I am asking "why doesn't this browser request work the way I want it to" I'm also asking what particular avenue of research I need to do to understand what is even going on here.
It sounds like curl is checking for a response concurrently with the sending the request, and it notices that a response has already occurred before it finishes sending the request. That's not normal webserver behavior, and apparently it treats it as meaning that it doesn't need to complete the request.
The browser's logic is different, it doesn't start reading from the network until after it has completed sending the entire request.
When the query parameter is valid, you should wait for the post data to be received completely before sending the response, then curl won't terminate the request. That will still allow you to complete processing asynchronously.

How to tell if an XMLHTTPRequest hit the browser cache

If it possible to tell (within javascript execution) if a GET XMLHTTPRequest hit the browser cache instead of getting its response from the server?
From the XMLHttpRequest spec:
For 304 Not Modified responses that are a result of a user agent
generated conditional request the user agent must act as if the server
gave a 200 OK response with the appropriate content.
In other words, the browser will always give status code 200 OK, even for requests that hit the browser cache.
However, the spec also says:
The user agent must allow author request headers to override automatic cache
validation (e.g. If-None-Match or If-Modified-Since), in which case
304 Not Modified responses must be passed through.
So, there is a workaround to make the 304 Not Modified responses visible to your JavaScript code.
When making an ajax request, You get the response code
if (request.readyState == 4) {
if (request.status == 200) { // this number.
...
status 200 means you are getting a fresh copy of the data:
The request has succeeded. The information returned with the response is dependent on the method used in the request -
status 304 means the data has not changed and you will get it from the browser cache:
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code.
Read more on Status Code
Update:
You can add a cache buster to your URL to guarantee that you always hit the server:
var ajaxUrl = "/path?cache="+(Math.random()*1000000);
From http://www.w3.org/TR/2012/WD-XMLHttpRequest-20121206/
For 304 Not Modified responses that are a result of a user agent
generated conditional request the user agent must act as if the server
gave a 200 OK response with the appropriate content. The user agent
must allow author request headers to override automatic cache
validation (e.g. If-None-Match or If-Modified-Since), in which case
304 Not Modified responses must be passed through. [HTTP]
I find this rather vague. My assumption would be if a resource is conditionally requested, you would see the 304 response code. But, as I explained in another comment (source: https://developers.google.com/speed/docs/best-practices/caching), there might not even be a request if the last response server http header for that resource had set Cache-Control: max-age or Expires set sometime in the future. In this case, I'm not sure what ought to happen.
This answer is based on the assumption that you mean browser only cache, with no 304's taking place (modified-since, etag etc).
Check how long the request took - if it was resolved from cache then it should take close to 0ms.
Do you use Firefox's Firebug?
Firebug has a "Net" panel with an "XHR" filtered view. You should be able to inspect the cache info via the request phase bar, checking the status and/or clicking the triangle to inspect "Headers".
Cached or not cached
Not all network requests are equal - some of them are loaded from the
browser cache instead of the network. Firebug provides status codes
for every request so you can quickly scan and see how effectively your
site is using the cache to optimize page load times.
Firebug Net Panel docs are here.
Chrome/Safari/Opera all have similar debugging tools. Just found a good list here (most should have tools to inspect XHR).
EDIT:
In order to somewhat redeem myself...
As ibu has answered, I'd also start by checking the status code of the response.
If you're using jQuery:
statusCode(added 1.5)
Map Default: {}
A map of numeric HTTP codes and functions to be called when the
response has the corresponding code. For example, the following will
alert when the response status is a 404:
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});
If the request is successful, the status code functions take the same
parameters as the success callback; if it results in an error, they
take the same parameters as the error callback.
jQuery sure does make life easy. :)
To check from a browser such as Google Chrome, hit F12 to open DevTools, navigate to Network, refresh to grab some data, filter by XHR, then click on the correct XHR request. Click on the "headers" sub-tab, then look at Response Headers -> cache-control.
If it says things like no-cache and max-age=0, then you are not caching.
If it says private, then your browser is caching, but the server is not.
If it says public, then you are caching both server side and client side.
More info at Mozilla.org

Get time from time.nist.gov NTP server using JavaScript?

How to do? I am a beginner coder - full references and code would help. I literally spent like 5 hours trying to find a solution to this - there are some references online but nothing works! And I don't have access to the NTP server and yes I have to use a public server - such as time.nist.gov.
Help!!!
Short answer:
Not doable.
Long answer:
Even if cross-origin policy would allow it, there's no way to get NTP directly via Ajax without PHP (or something) relaying your request. First reason is that time servers normally stay on UDP port 123; there's no way for Ajax to do UDP; if that's not enough, when Ajax sends a request to a server, it expects to see in response some HTTP headers, some status codes, a response body, etc. NTP doesn't keep that structure, it only sends a string. And there is no raw socket connection support in HTML5 either.
But what you can do with Ajax is look at the request headers because most responses come back with a header that looks like this:
Date:Mon, 21 May 2012 15:30:58 GMT
And there's your time.

Using HTTP status codes to reflect success/failure of Web service request?

I'm implementing a Web service that returns a JSON-encoded payload. If the service call fails -- say, due to invalid parameters -- a JSON-encoded error is returned. I'm unsure, however, what HTTP status code should be returned in that situation.
On one hand, it seems like HTTP status codes are for HTTP: even though an application error is being returned, the HTTP transfer itself was successful, suggesting a 200 OK response.
On the other hand, a RESTful approach would seem to suggest that if the caller is attempting to post to a resource, and the JSON parameters of the request are invalid somehow, that a 400 Bad Request is appropriate.
I'm using Prototype on the client side, which has a nice mechanism for automatically dispatching to different callbacks based on HTTP status code (onSuccess and onFailure), so I'm tempted to use status codes to indicate service success or failure, but I'd be interested to hear if anyone has opinions or experience with common practice in this matter.
Thanks!
http status code are just for indicating the status of the application response.
and as you said, if json parameters as somehow invalid, a 400 status code is an appropriate answer.
so yes, it is a really good idea to use http status code. de plus, status code are then easy to understand as they don't change from an application (web services) to another
You should definitely use the proper status codes since they are exactly for this purpose, not to indicate the status of the HTTP request itself. By this way you can redirect the response to the appropriate function/branch before parsing it which will lead to a much tidier code in the client side.

Categories

Resources