I'm working on a very simple Sidebar Gadget to analyze my router's monthly bandwidth usage and determine how far ahead or behind I am for that month. The data is located in a router-hosted, password protected webpage (I'm using DD-WRT, if it matters). I'd like to pass a page request to the router with Javascript, along with all the authentication information, to retrieve the page all in one go, but I can't seem to find the proper syntax for that. Any ideas?
Here's my code so far:
var ua = navigator.userAgent.toLowerCase();
if (!window.ActiveXObject){
req = new XMLHttpRequest();
}else if (ua.indexOf('msie 5') == -1){
req = new ActiveXObject("Msxml2.XMLHTTP");
}else{
req = new ActiveXObject("Microsoft.XMLHTTP");
}
req.open('GET', 'http://192.168.1.1/Status_Internet.asp', false, "username", "password");
req.send(null);
if(req.status == 200){
dump(req.responseText);
} else{
document.write("Error");
}
document.write("Second Error");
Firebug indicates that it throws an error on req.send(null) - specifically,
Access to restricted URI denied" code: "1012.
It may be because of the same-origin policy, but in that case what can I use instead of an xmlhttpRequest?
It is because of the same-origin policy, the alternative is an iframe but that will not really give you what you wish for.
If it is http-auth you used to be able to request the page with http://username:pass#site but i must admit i haven't tried to use that for a long time, so i don't know if it is still supported.
EDIT:
If this doesn't work, maybe you can use basic http auth as described here: http://en.wikipedia.org/wiki/Basic_access_authentication but this would require you to sue a serverside proxy, since you can't manipulate the request headers from javascript when xhr is not an option.
You need to add a Authorization header to the request. I'm not an AJAX expert, so I'm not sure if you can modify header fields in AJAX requests. If you can't, then you're doomed.
If you can, then this Wikipedia article contains an example what it must look like.
That's a security feature: you see, there are malicious scripts that used a similar technique to hack the routers (who changes their router password anyway? Apparently not Joe X. Schmoe).
Under the Same Origin Policy, AJAX requests are limited to the domain (and port) whence they originated: therefore, from a local page, you can't make a request to 192.168.1.1:80 .
There is a possible workaround - a server-side proxy (e.g. a PHP script that fetches the router pages for you) inside your network.
If the same-origin policy is not the issue, then
load jQuery on your page.
and use jQuery's $.ajax method.
$.ajax({
url: "path/to/your/page.html", // self-explanatory
password:"your password", // a string with your password.
success: function(data){ // on sucsess:
$("someDiv").html(data); // load in the retrived page
}
});
See the jQuery ajax API for details.
Related
Access to restricted URI denied" code: "1012 [Break On This Error]
xhttp.send(null);
function getXML(xml_file) {
if (window.XMLHttpRequest) {
var xhttp = new XMLHttpRequest(); // Cretes a instantce of XMLHttpRequest object
}
else {
var xhttp = new ActiveXObject("Microsoft.XMLHTTP"); // for IE 5/6
}
xhttp.open("GET",xml_file,false);
xhttp.send(null);
var xmlDoc = xhttp.responseXML;
return (xmlDoc);
}
I'm trying to get data from a XML file using JavaScript. Im using Firebug to test and debug on Firefox.
The above error is what I'm getting. It works in other places i used the same before, why is acting weird here?
Can someone help me why it's occuring?
Update:
http://jquery-howto.blogspot.com/2008/12/access-to-restricted-uri-denied-code.html
I found this link explaining the cause of the problem. But I didn't get what the solution given means can someone elaborate?
Another possible cause of this is when you are working with a .html file directly on the file system. For example, if you're accessing it using this url in your browser: C:/Users/Someguy/Desktop/MyProject/index.html
If that then has to make an ajax request, the ajax request will fail because ajax requests to the filesystem are restricted. To fix this, setup a webserver that points localhost to C:/Users/Someguy/Desktop/MyProject and access it from http://localhost/index.html
Sounds like you are breaking the same origin policy.
Sub domains, different ports, different protocols are considered different domains.
Try adding Access-Control-Allow-Origin:* header to the server side script that feeds you the XML. If you don't do it in PHP (where you can use header()) and try to read a raw XML file, you probably have to set the header in a .htaccess file by adding Header set Access-Control-Allow-Origin "*". In addition you might need to add Access-Control-Allow-Headers:*.
Also I'd recommend to replace the * in production mode to disallow everybody from reading your data and instead add your own url there.
Without code impossible to say, but you could be running foul of the cross-site ajax limitation: you cannot make ajax requests to other domains.
I have run in to a problem. Please help with your expertise.
I am developing web solution for a company. They have provided me Web API Method (REST). This API is in their domain. I am too access this from my domain. Even client has also already whitelisted my domain.
I am trying to call this method using below. But no luck. I am getting this below error.
Error NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
function GetCustomerInfo()
{
var Url = "http://webapi.company.com/vx.x/customer/get?format=xml&mobile=9876543210" ;
myXmlHttp = new XMLHttpRequest();
myXmlHttp.withCredentials = true;
myXmlHttp.onreadystatechange = ProcessRequest;
myXmlHttp.open( "GET", Url, true,"UID","PWD");
myXmlHttp.send();
}
function ProcessRequest()
{
if(this.readyState == this.DONE)
{
if(this.status == 200 && this.responseXML != null )
{
alert ("Received Resoponse from Server");
}
else
{
alert ("Some Problem");
}
}
}
I am able to access this method from RESTClient in firefox plugin.
Even I am able to access this method copying credentials in URL as below in browser address bar. I get anticipated response XML
http://UID:PWD#webapi.company.com/vx.x/customer/get?format=xml&mobile=9876543210
Please enlighten me where I am wrong. Perhaps JSONP can come to my help. But why i am not able to access this API using XMLHttpRequest.
Regards
Rajul
The same origin policy of the browser does not allow you to send XMLHttpRequests to a different domain. The reason you can access it through a firefox plugin or the address bar is that the same origin policy is not applied there.
You are right, JSONP could solve your problem, although you may run into trouble because you do not control the serverside.
In response to your comment: In order to use JSONP effectively, the server will need to return not only the data you need in JSON format, but also javascript code to invoke a callback when the request is done. If you do not control the data that is returned, you can not add the necessary code for this. The wikipedia article gives a good example for the general case.
I have never used CORS, thus can not give you much information on it. It seems like a better solution, but I imagine it is not incredibly compatible across browsers. Also, as I understand it, you will need control of the server as well, as it seems to require additional HTTP headers.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Ways to circumvent the same-origin policy
I am making a personal web page that extracts the lottery powerball numbers and displays them. I have had success for all but this one link:
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "get", "http://www.powerball.com/powerball/pb_numbers.asp", false );
xmlHttp.send(null);
document.body.innerHTML = xmlHttp.responseText;
I checked the xmlHTTP.status and it is 0. However, using Live HTTP headers app I see that the request is sent and I do get a successful HTTP/1.0 200 OK where the page was received on my end. But, there is nothing received in the xmlHTTP object. No responseText, just status 0 for get not initialized.
EDIT: I do not see a Access-Control-Allow-Origin: directive in the return header. Why is this if I am being restricted because I am from a different domain?
You can't use XHR to read data from different origins. Since the request is made as the user of the browser, it is done with everything that might authenticate the user so might retrieve confidential information (which you could then use XHR to copy to your own server).
See this stackoverflow question for work arounds.
I'm not sure how it works nor it's capabilties but you seem to have an answer above on why it doesn't work. I recommend you to use ajax instead, it's simple and works just great.
Here's an example where I use it:
var site = $.ajax({
url: "http://google.com",
type: "GET",
dataType: "html",
async: false
}).responseText;
document.body.innerHTML = site;
Good luck,
Your problem here is the same origin policy. You won't be able to get any data from that website using AJAX unless that website provides a JSONP API (and even then it's not technically AJAX).
You can achieve what you are doing to some extent with an iframe but you will have to include the entire page and not just the relevant part of it.
If what you need to do is Web scraping then you will have some server-side proxy to do it.
Some tools that might help you:
YQL
Yahoo Pipes
Notable Web scraping tools on Wikipedia
Alternative to cross domain ajax is:
write proxy which will request the remote server using CURL
call that proxy file from ajax call
I use the jQuery ajax functions to access a web service, but the server, instead of returning a response with a status code describing a problem, the request is redirected to a page with a 200 header, describing the problem. I can't make any changes to this, so I need to solve it on the client somehow.
Example:
A request goes to some URL which is not found, so I receive a 302 Redirect to another location. A new request is sent, and I receive a 200 OK, thus preventing the error callback to fire.
Is there some way I can prevent the ajax request to follow redirects and instead invoke a callback, preferably the error method. Alternatively, is it possible to detect if a redirect has happened in the client?
I find your question interesting, but the problem in whole seems me more a misunderstanding. At least I'll try to explain my understanding of the problem.
The silent (transparent) redirection is the part of XMLHttpRequest specification (see here especially the words "... transparently follow the redirect ..."). The standard mention only that the user agent (the web browser) can prevent or notify of certain kinds of automatic redirections, but it's not a part of XMLHttpRequest. It's the part of HTTP client configuration (OS configuration) or the web browser configuration. So jQuery.ajax can't have any option where you can prevent redirection.
You can see that HTTP redirection is the part of HTTP protocol and not a part of XMLHttpRequest. So it's on the another level of abstraction or the network stack. For example the data from the XMLHttpRequest can be retrieved from the HTTP proxy or from the local browser cache, and it's the part of HTTP protocol. Mostly the server which provide the data and not the client can influence on caching.
You can compare the requirement from your question with the requirement to prevent changing of IP address of the web server or the changing of the IP route during the communication. All the things can be interesting in some scenarios, but there are parts of another level of the communication stack and can't be managed by jQuery.ajax or XMLHttpRequest.
The XMLHttpRequest standard say that the client configuration can have options which prevent redirection. In case of "Microsoft world", which I better know, you can look at WinHttpSetOption function which can be used to set WINHTTP_OPTION_DISABLE_FEATURE option with the WINHTTP_DISABLE_REDIRECTS value. Another way are the usage of WINHTTP_OPTION_REDIRECT_POLICY option with the WINHTTP_OPTION_REDIRECT_POLICY_NEVER value. One more feature which one can use in Windows is the WinHttpSetStatusCallback function which can set callback function received some notifications like WINHTTP_CALLBACK_FLAG_REDIRECT.
So it's do possible to implement your requirements in general, but the solution will be probably not independent from the operation system or the web browser and be not on the level of jQuery.ajax or XMLHttpRequest.
I don't believe it is possible. The underlying library (XHR) makes the new request transparently. That being said, what I have done in these situations (usually a session-timeout type of deal that takes me to a login page) is send back a custom response header. I also have setup a global ajax handler that checks for the presence of that header, and responds appropriately when present (for example, redirecting the whole page to the login screen).
In case you're interested, here's the jQuery code I have to watch for that custom header:
/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
if (xhr.readyState == 4)
{
if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
{
window.location.href='sessionExpired.html'; //whatever
}
}
}
$(document).ajaxComplete(checkSession)
I found a feature to check if your call has been redirected. It's xhr.state(): if it's "rejected" then a redirection happened.
Example with success callback:
request.success(function(data, textStatus, xhr)
{
if(xhr.state() == "resolved")
{
//no redirection
}
if(xhr.state() == "rejected")
{
//redirection
}
});
Example with error callback:
request.error(function(xhr, textStatus)
{
if (xhr.state() == "rejected")
{
//redirection
location.href = "loginpage";
} else
{
//some other error happened
alert("error");
}
});
I can't possibly add to the insightful wisdom of the previous coders who've responded, but I will add a specific case that others may find useful to know about.
I came across this 302 silent redirect in the context of SharePoint. I have some simple Javascript client code that pings a SharePoint sub-site, and if it receives a 200 HTTP response, it relocates to that site, via window.location. If it receives anything else, it gives the user a notice that the site doesn't exist.
However, in the case where the site exists but the user does not have permission, SharePoint silently redirects to an AccessDenied.aspx page. SharePoint has already done the HTTP 401 authentication handshake at the server/farm level - the user has access to SharePoint. But the access to the sub-site is handled I suppose using database flags of some sort. The silent redirect bypasses my "else" clause, so I can't throw up my own error. In my case, this is not a show-stopper - it is consistent predictable behavior. But it was a little surprising, and I learned something about HTTP requests in the process!
I was interested in the same thing and could not find the state() method mentioned by Takman and did a little digging for myself. For the sake of people turning up here in search of an answer, here are my findings:
As stated multiple times, you cannot prevent redirects, but you can detect them. According to MDN you can use the responseURL of the XMLHttpRequestObject, which will contain the final URL the response came from, after all redirects. Only caveat is that it is not supported by Internet Explorer (Edge has it). Since the xhr/jqXHR passed into the success/done function of jquery is an extension of the actual XMLHttpRequest, it should be available there, too.
While it is not possible to disable location redirect following in XmlHttpRequests, it is when using fetch():
fetch('url', {redirect: manual});
I suppose you receive a 200 response because the second time there is no redirection, because the 404 page does not expire, it is saved in the cache. That is to say that the second time the browser gives you the page in the cache.
There is a property "cache" in the ajax jquery.
http://api.jquery.com/jQuery.ajax/
You should write it to "false"
I'm not sure if this will apply in your case, but you can write code to respond to specific status codes in AJAX function -
$.ajax({
url: '/admin/secret/data',
type: 'POST',
contentType: 'application/json; charset=utf-8',
statusCode: {
200: function (data) {
alert('302: Occurred');
// Bind the JSON data to the UI
},
401: function (data) {
alert('401: Occurred');
// Handle the 401 error here.
}
}
});
In the request headers in the case of ajax request you will have the following
X-Requested-With XMLHttpRequest
By this criteria on the server side you can filter requests.
I have written an XMLHttpRequest which runs fine but returns an empty responseText.
The javascript is as follows:
var anUrl = "http://api.xxx.com/rates/csv/rates.txt";
var myRequest = new XMLHttpRequest();
callAjax(anUrl);
function callAjax(url) {
myRequest.open("GET", url, true);
myRequest.onreadystatechange = responseAjax;
myRequest.setRequestHeader("Cache-Control", "no-cache");
myRequest.send(null);
}
function responseAjax() {
if(myRequest.readyState == 4) {
if(myRequest.status == 200) {
result = myRequest.responseText;
alert(result);
alert("we made it");
} else {
alert( " An error has occurred: " + myRequest.statusText);
}
}
}
The code runs fine. I can walk through and I get the readyState == 4 and a status == 200 but the responseText is always blank.
I am getting a log error (in Safari debug) of Error dispatching: getProperties which I cannot seem to find reference to.
I have run the code in Safari and Firefox both locally and on a remote server.
The URL when put into a browser will return the string and give a status code of 200.
I wrote similar code to the same URL in a Mac Widget which runs fine, but the same code in a browser never returns a result.
Is http://api.xxx.com/ part of your domain? If not, you are being blocked by the same origin policy.
You may want to check out the following Stack Overflow post for a few possible workarounds:
Ways to circumvent the same-origin policy
PROBLEM RESOLVED
In my case the problem was that I do the ajax call (with $.ajax, $.get or $.getJSON methods from jQuery) with full path in the url param:
url: "http://mydomain.com/site/cgi-bin/serverApp.php"
But the correct way is to pass the value of url as:
url: "site/cgi-bin/serverApp.php"
Some browser don't conflict and make no distiction between one text or another, but in Firefox 3.6 for Mac OS take this full path as "cross site scripting"... another thing, in the same browser there is a distinction between:
http://mydomain.com/site/index.html
And put
http://www.mydomain.com/site/index.html
In fact it is the correct point view, but most implementations make no distinction, so the solution was to remove all the text that specify the full path to the script in the methods that do the ajax request AND.... remove any BASE tag in the index.html file
base href="http://mydomain.com/" <--- bad idea, remove it!
If you don't remove it, this version of browser for this system may take your ajax request like if it is a cross site request!
I have the same problem but only on the Mac OS machine. The problem is that Firefox treat the ajax response as an "cross site" call, in any other machine/browser it works fine. I didn't found any help about this (I think that is a firefox implementation issue), but I'm going to prove the next code at the server side:
header('Content-type: application/json');
to ensure that browser get the data as "json data" ...
The browser is preventing you from cross-site scripting.
If the url is outside of your domain, then you need to do this on the server side or move it into your domain.
This might not be the best way to do it. But it somehow worked for me, so i'm going to run with it.
In my php function that returns the data, one line before the return line, I add an echo statement, echoing the data I want to send.
Now sure why it worked, but it did.
Had a similar problem to yours. What we had to do is use the document.domain solution found here:
Ways to circumvent the same-origin policy
We also needed to change thins on the web service side. Used the "Access-Control-Allow-Origin" header found here:
https://developer.mozilla.org/En/HTTP_access_control