I am trying to detect if a user is using some kind of extension in his browser that could prevent my site from working properly and if so, display a message for the user.
I am testing with an extension called uMatrix, but there are others with a similar approach.
My problem is, that kind of extension will block my HTTP request, but that doesn't return a proper status code (like 403, 404, 500, etc). Instead, when I catch my request, I just get a
Error: Network Error
at [my file name and line number here]
at XMLHttpRequest.handleError (xhr.js:83)
I believe this same error would be thrown in other circumstances, like lack of internet connection, so I can't assume this Network Error means that the user has a "HTTP request blocker".
I was reading a lot about identifying AdsBlocker on this thread and other places, but I don't think it applies to my issue.
Any ideas on how to identify that a user is blocking my HTTP Requests? (Either on purpose or through a browser extension)
I thought I would share here the solution I found, even though I don't think that's the best answer yet.
I am using Axios for my API requests and I found this thread here:
https://github.com/axios/axios/issues/383#issuecomment-234079506
What they suggest it's to check if the response has a status (but in latest Axios, they don't even return a response). If not, it means the server was never reached. That could still mean that there is no internet connection, not necessarily an extension blocked the request. So I adjusted my message to cover both scenarios.
My final code was something like this:
// Note the use of "HEAD", since that will be faster than a "GET"
axios.head(server_url_for_testing).catch(function(error) {
if (!error.response) {
// Display my warning message
}
})
Related
I've an issue requesting some data in JS and i get status code 503 and also a message that i don't know what it means,it seems like the memory located to the request is not enought and i would like to know why and how to solve, here the screenshot:
You can manually see it on chrome's dev tools (network section) on this page: PAGE
You can also notice that if you refresh the page more times the requests that fails are everytime different.
I won't write all the code here because is too long, but i leave the link, i'm sorry but this is not my own script and it is compressed.
this is the file that triggers the error.
CODE
THIS IS THE ERROR FROM CPANEL:
couldn't create child process: /usr/sbin/suphp for /home/smmmainp/public_html/index.php, referer: https://smm-mainpanel.com/services
I looked up your site and your server is returning an Exceeded Resource Limit Error Show Image.
"The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later".
It is not a JavaScript problem, it is an HTTP Request problem, server-side. The "jQuery" that's showing in your Console is probably the Request Initiator, and when some problem happens with your Request, the jQuery needs to Handle it and send an error message. But stills a Server-Side error.
You need to look into your cPanel, go to "Stats" page and look your HTTP Request Limit, in order to know how much requests daily (or per hour) your server handle. Review your Server Provider Plan and contact them.
Best regards!
For some reason, while using AJAX (with my dashcode developed application) the browser just stops uploading and returns status codes of 0. Why does this happen?
Another case:
It could be possible to get a status code of 0 if you have sent an AJAX call and a refresh of the browser was triggered before getting the AJAX response. The AJAX call will be cancelled and you will get this status.
In my experience, you'll see a status of 0 when:
doing cross-site scripting (where access is denied)
requesting a URL that is unreachable (typo, DNS issues, etc)
the request is otherwise intercepted (check your ad blocker)
as above, if the request is interrupted (browser navigates away from the page)
Same problem here when using <button onclick="">submit</button>. Then solved by using <input type="button" onclick="">
Status code 0 means the requested url is not reachable. By changing http://something/something to https://something/something worked for me. IE throwns an error saying "permission denied" when the status code is 0, other browsers dont.
It is important to note, that ajax calls can fail even within a session which is defined by a cookie with a certain domain prefixed with www. When you then call your php script e.g. without the www. prefix in the url, the call will fail and viceversa, too.
Because this shows up when you google ajax status 0 I wanted to leave some tip that just took me hours of wasted time... I was using ajax to call a PHP service which happened to be Phil's REST_Controller for Codeigniter (not sure if this has anything to do with it or not) and kept getting status 0, readystate 0 and it was driving me nuts. I was debugging it and noticed when I would echo and return instead of exit the message I'd get a success. Finally I turned debugging off and tried and it worked. Seems the xDebug debugger with PHP was somehow modifying the response. If your using a PHP debugger try turning it off to see if that helps.
I found another case where jquery gives you status code 0 -- if for some reason XMLHttpRequest is not defined, you'll get this error.
Obviously this won't normally happen on the web, but a bug in a nightly firefox build caused this to crop up in an add-on I was writing. :)
This article helped me. I was submitting form via AJAX and forgotten to use return false (after my ajax request) which led to classic form submission but strangely it was not completed.
"Accidental" form submission was exactly the problem I was having. I just removed the FORM tags altogether and that seems to fix the problem. Thank you, everybody!
I had the same problem, and it was related to XSS (cross site scripting) block by the browser. I managed to make it work using a server.
Take a look at: http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/282972/why-am-i-getting-xmlhttprequest.status0
We had similar problem - status code 0 on jquery ajax call - and it took us whole day to diagnose it. Since no one had mentioned this reason yet, I thought I'll share.
In our case the problem was HTTP server crash. Some bug in PHP was blowing Apache, so on client end it looked like this:
mirek#toccata:~$ telnet our.server.com 80
Trying 180.153.xxx.xxx...
Connected to our.server.com.
Escape character is '^]'.
GET /test.php HTTP/1.0
Host: our.server.com
Connection closed by foreign host.
mirek#toccata:~$
where test.php contained the crashing code.
No data returned from the server (not even headers) => ajax call was aborted with status 0.
In my case, it was caused by running my django server under http://127.0.0.1:8000/ but sending the ajax call to http://localhost:8000/. Even though you would expect them to map to the same address, they don't so make sure you're not sending your requests to localhost.
In our case, the page link was changed from https to http. Even though the users were logged in, they were prevented from loading with AJAX.
In my case, setting url: '' in ajax settings would result in a status code 0 in ie8.. It seems ie just doesn't tolerate such a setting.
For me, the problem was caused by the hosting company (Godaddy) treating POST operations which had substantial response data (anything more than tens of kilobytes) as some sort of security threat. If more than 6 of these occurred in one minute, the host refused to execute the PHP code that responded to the POST request during the next minute. I'm not entirely sure what the host did instead, but I did see, with tcpdump, a TCP reset packet coming as the response to a POST request from the browser. This caused the http status code returned in a jqXHR object to be 0.
Changing the operations from POST to GET fixed the problem. It's not clear why Godaddy impose this limit, but changing the code was easier than changing the host.
I think I know what may cause this error.
In google chrome there is an in-built feature to prevent ddos attacks for google chrome extensions.
When ajax requests continuously return 500+ status errors, it starts to throttle the requests.
Hence it is possible to receive status 0 on following requests.
In an attempt to win the prize for most dumbest reason for the problem described.
Forgetting to call
xmlhttp.send(); //yes, you need this pivotal line!
Yes, I was still getting status returns of zero from the 'open' call.
In my case, I was getting this but only on Safari Mobile. The problem is that I was using the full URL (http://example.com/whatever.php) instead of the relative one (whatever.php). This doesn't make any sense though, it can't be a XSS issue because my site is hosted at http://example.com. I guess Safari looks at the http part and automatically flags it as an insecure request without inspecting the rest of the URL.
In my troubleshooting, I found this AJAX xmlhttpRequest.status == 0 could mean the client call had NOT reached the server yet, but failed due to issue on the client side. If the response was from server, then the status must be either those 1xx/2xx/3xx/4xx/5xx HTTP Response code. Henceforth, the troubleshooting shall focus on the CLIENT issue, and could be internet network connection down or one of those described by #Langdon above.
In my case, I was making a Firefox Add-on and forgot to add the permission for the url/domain I was trying to ajax, hope this saves someone a lot of time.
Observe the browser Console while making the request, if you are seeing "The Same Origin Policy disallows reading the remote resource at http ajax..... reason: cors header ‘access-control-allow-origin’ missing" then you need to add "Access-Control-Allow-Origin" in response header. exa: in java you can set this like response.setHeader("Access-Control-Allow-Origin", "*") where response is HttpServletResponse.
I don't know if this is a duplicate post or not, sorry if it is. I'm using jquery.getJSON to load a json on my server which works just fine. Although, if I try and load a json file on a different server it doesn't work. I know I don't have any code here (because there's not much point) but I just want to know if I'm using it wrong or if it isn't supposed to load external files. I'm using the iOS Safari browser if that effects anything.
EDIT: I've looked at the console (idk what the error thing really means, it's just red with an x by the url it's trying to get the json from) and it looks like it's not actually receiving the data. Plus, do remember I'm on iOS, not desktop so I couldn't look at the console in the "Develop tab :P
EDIT 2: Great! I think I got it working! http://skitty.xyz/getJSON/
You're most likely encountering a path issue; the purpose of $.getJSON is to acquire data via http GET request so yes, it is intended to work remotely. To diagnose your issue, make certain you can access the json file in your browser first: http://domain.com/my_data.json. If that works, use that as the URL you pass into $.getJSON:
$.getJSON( 'http://domain.com/my_data.json', function(data) {
// do something with your data
});
http://api.jquery.com/jquery.getjson/
jquery.getJSON uses ajax which is all about external resources. Here's a couple things to check for if it's not working on an external resource:
1: Is the path you specified correct? The usage is jquery.getJSON(path, callback). The path should be something you can just drop in your browser and see. If an incorrect path is your problem, you'll see a 404 in the console.
2: Is the resource http and your site https? Non-secure resources on secure pages will get blocked by browser security features. You'd see a error to this effect in the console.
3: Is CORS (Cross-origin resource sharing) enabled for your site on the external resource? Servers will sometimes use a whitelist of IPs and domains to determine what origins are allowed to make requests of it. You'd also see an error to this effect in the console.
There probably some other things to look for but this is where I'd start.
Also, by all means, use the debugging features of Safari to LQQK at the actual HTTP data-streams that are passing back-and-forth in response to what you're doing. (You might need to click on a preference to see the "Develop" menu, which will take you to "Show Web Inspector" and its Network tab.)
This approach will instantly answer many questions that a JavaScript-centered approach will not so-readily tell you. (And of course, you can look at the JavaScript console too ... and at the same time.) "The actual data streams, please." Safari will tell you "exactly what bytes" your app actually sent to the server, and "exactly what bytes" the server sent in return. "Priceless!™"
Are you saying you are using jquery ajax request to load some json data from a server?
check the "not working server" has the same end point as your server.
Check if the url you want to get data from is correct.
check if console logged any errors.
Also quote from http://api.jquery.com/jquery.getjson/
"Additional Notes:
Due to browser security restrictions, most "Ajax" requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, port, or protocol.
Script and JSONP requests are not subject to the same origin policy restrictions."
I'm trying to determine the best practice in a REST API for determining whether the client can access a particular resource. Two quick example scenarios:
A phone directory lookup service. Client looks up a phone number by accessing eg.
GET http://host/directoryEntries/numbers/12345
... where 12345 is the phone number to try and find in the directory. If it exists, it would return information like the name and address of the person whose phone number it is.
A video format shifting service. Client submits a video in one format to eg.
POST http://host/videos/
... and receives a 'video GUID' which has been generated by the server for this video. Client then checks eg.
GET http://host/videos/[GUID]/flv
... to get the video, converted into the FLV format, if the converted version exists.
You'll notice that in both cases above, I didn't mention what should happen if the resource being checked for doesn't exist. That's my question here. I've read in various other places that the proper RESTful way for the client to check whether the resource exists here is to call HEAD (or maybe GET) on the resource, and if the resource doesn't exist, it should expect a 404 response. This would be fine, except that a 404 response is widely considered an 'error'; the HTTP/1.1 spec states that the 4xx class of status code is intended for cases in which the client 'seems to have erred'. But wait; in these examples, the client has surely not erred. It expects that it may get back a 404 (or others; maybe a 403 if it's not authorized to access this resource), and it has made no mistake whatsoever in requesting the resource. The 404 isn't intended to indicate an 'error condition', it is merely information - 'this does not exist'.
And browsers behave, as the HTTP spec suggests, as if the 404 response is a genuine error. Both Google Chrome and Firebug's console spew out a big red "404 Not Found" error message into the Javascript console each time a 404 is received by an XHR request, regardless of whether it was handled by an error handler or not, and there is no way to disable it. This isn't a problem for the user, as they don't see the console, but as a developer I don't want to see a bunch of 404 (or 403, etc.) errors in my JS console when I know perfectly well that they aren't errors, but information being handled by my Javascript code. It's line noise. In the second example I gave, it's line noise to the extreme, because the client is likely to be polling the server for that /flv as it may take a while to compile and the client wants to display 'not compiled yet' until it gets a non-404. There may be a 404 error appearing in the JS console every second or two.
So, is this the best or most proper way we have with REST to check for the existence of a resource? How do we get around the line noise in the JS console? It may well be suggested that, in my second example, a different URI could be queried to check the status of the compilation, like:
GET http://host/videos/[GUID]/compileStatus
... however, this seems to violate the REST principle a little, to me; you're not using HTTP to its full and paying attention to the HTTP headers, but instead creating your own protocol whereby you return information in the body telling you what you want to know instead, and always return an HTTP 200 to shut the browser up. This was a major criticism of SOAP - it tries to 'get around' HTTP rather than use it to its full. By this principle, why does one ever need to return a 404 status code? You could always return a 200 - of course, the 200 is indicating that the a resource's status information is available, and the status information tells you what you really wanted to know - the resource was not found. Surely the RESTful way should be to return a 404 status code.
This mechanism seems even more contrived if we apply it to the first of my above examples; the client would perhaps query:
GET http://host/directoryEntries/numberStatuses/12345
... and of course receive a 200; the number 12345's status information exists, and tells you... that the number is not found in the directory. This would mean that ANY number queried would be '200 OK', even though it may not exist - does this seem like a good REST interface?
Am I missing something? Is there a better way to determine whether a resource exists RESTfully, or should HTTP perhaps be updated to indicate that non-2xx status codes should not necessarily be considered 'errors', and are just information? Should browsers be able to be configured so that they don't always output non-2xx status responses as 'errors' in the JS console?
PS. If you read this far, thanks. ;-)
It is perfectly okay to use 404 to indicate that resource is not found. Some quotes from the book "RESTful Web Services" (very good book about REST by the way):
404 indicates that the server can’t map the client’s URI to a
resource. [...] A web service may use a 404 response as a signal to
the client that the URI is “free”; the client can then create a new
resource by sending a PUT request to that URI. Remember that a 404 may
be a lie to cover up a 403 or 401. It might be that the resource
exists, but the server doesn’t want to let the client know about it.
Use 404 when service can't find requested resource, do not overuse to indicate the errors which are actually not relevant to the existence of resource. Also, client may "query" the service to know whether this URI is free or not.
Performing long-running operations like encoding of video files
HTTP has a synchronous request-response model. The client opens an
Internet socket to the server, makes its request, and keeps the socket
open until the server has sent the response. [...]
The problem is not all operations can be completed in the time we
expect an HTTP request to take. Some operations take hours or days. An
HTTP request would surely be timed out after that kind of inactivity.
Even if it didn’t, who wants to keep a socket open for days just
waiting for a server to respond? Is there no way to expose such
operations asynchronously through HTTP?
There is, but it requires that the operation be split into two or more
synchronous requests. The first request spawns the operation, and
subsequent requests let the client learn about the status of the
operation. The secret is the status code 202 (“Accepted”).
So you could do POST /videos to create a video encoding task. The service will accept the task, answer with 202 and provide a link to a resource describing the state of the task.
202 Accepted
Location: http://tasks.example.com/video/task45543
Client may query this URI to see the status of the task. Once the task is complete, representation of resource will become available.
I think you have changed the semantics of the request.
With a RESTful architecture, you are requesting a resource. Therefore requesting a resource that does not exist or not found is considered an error.
I use:
404 if GET http://host/directoryEntries/numbers/12345 does not exist.
400 is actually a bad request 400 Bad Request
Perhaps, in your case you could think about searching instead.
Searches are done with query parameters on a collection of resources
What you want is
GET http://host/directoryEntries/numbers?id=1234
Which would return 200 and an empty list if none exist or a list of matches.
IMO the client has indeed erred in requesting a non-existent resource. In both your examples the service can be designed in a different way so an error can be avoided on the client side. For example, in the video conversion service as the GUID has already been assigned, the message body at videos/id can contain a flag indicating whether the conversion was done or not.
Similarly, in the phone directory example, you are searching for a resource and this can be handled through something like /numbers/?search_number=12345 etc. so that the server returns a list of matching resources which you can then query further.
Browsers are designed for working with the HTTP spec and showing an error is a genuine response (pretty helpful too). However, you need to think about your Javascript code as a separate entity from the browser. So you have your Javascript REST client which knows what the service is like and the browser which is sort of dumb with regards to your service.
Also, REST is independent of protocols in theory. HTTP happens to be the most common protocol where REST is used. Another example I can think of is Android content providers whose design is RESTful but not dependent on HTTP.
I've only ever seen GET/HEAD requests return 404 (Not Found) when a resource doesn't exist. I think if you are trying to just get a status of a resource a head request would be fine as it shouldn't return the body of a resource. This way you can differentiate between requests where you are trying to retrieve the resource and requests where you are trying to check for their existance.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Edit: I remember reading about an alternative solution by adding a header to the original request that indicated how the server should handle 404 errors. Something along the lines of responding with 200, but an empty body.
I'm having the following problem in a Safari extension. I ask the user to provide their username/password for a web service and send off a quick request to verify that the credentials are correct. If they are not, the service will respond with a 401 as I believe it should. The problem is that Safari seems to intercept this response before my javascript code can handle it, showing the grey login box instead of letting me handle the error.
Is there anything I can do about this? I'm using a js library to make the call, but it's functionally equivalent to the following jQuery.
$.ajax({
type: "GET",
url: url,
username: username,
password: password,
success: function() { /* handle success */ },
error: function() { /* handle error */ }
});
As far as I'm aware (after having had this issue myself) there's no way you'll get Safari to stop intercepting a 401. If those findings are correct, the only way is creative (read: mis-) use of another error code, e.g. 403, or using a custom one (see below).
Of course, this assumes that you have access to changing the status code sent back from the web service (it's not entirely clear from the question if you developed the web service too).
403, of course, really says "you're already authenticated, but not authorized to access this resource", which isn't correct (hence "misuse"), but at least it has no side effects in browsers that I'm aware of.
400 is sometimes used as an alternative, but since that one ("bad request") is really meant to signify a HTTP protocol error, it may cause side effects (never seen or heard of it happening, but potentially, it might cause an over-helpful attempt by some future browser or anti-hijacking software to start troubleshooting/diagnostics).
412 is another alternative that I've seen used ("precondition failed"), but it actually is meant to indicate that the server didn't live up to the preconditions the request set.
Or you could make up your own non-standard 4xx error - e.g. 461 - which is allowed (notice that twitter has a custom 420 status code, for example)
A more correct approach would be to continue to use 401 as the error code but not send the WWW-Authenticate header when the credentials have been sent but they were not correct.
That no longer triggers the browser's dialog and allows you to process 401 directly.