Coding with XMLHttpRequest for Safari Extension - javascript

In my extension, I create Access Level as "All" as well as I add whitelists as http://*/* too for every domain.
And I have following code in my JS file (which run as end script):
var feedbackmsg = "message goes here";
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', 'http://mysitename.com/feedback.php', true);
xmlhttp.onreadystatechange = handleServerResponse;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("html=" + feedbackmsg);
function handleServerResponse() {
if (xmlhttp.readyState == 4) {
alert(xmlhttp.getAllResponseHeaders());
if (xmlhttp.status == 200) {
alert("send");
} else {
alert("error");
}
}
}
Whenever I run it, I am getting no header respond in alert box as well as error alert message. How can I resolve the problem?

Whether or not it's an extension, XMLHttpRequest (if injected into a page) isn't allowed to access anything outside the page's current domain, I think. The console just says that the request was cancelled. At least, that was the case for me when I tested it just now. (I didn't have any urls in the whitelist or blacklist when I tested, but the Access option was set to "all".)
You can try going to the same domain as the one you want to "call" with the XHR object in your code, and see if it succeeds then. If it does, you'll know it's because the domain of the page and the XHR request must match.
However, it appears you can do cross-site ajax request from the extension's global page (oddly enough). At least it seemed to work for me just now. That's actually a little scary (I'd prefer it to be more difficult to call up a random server from an extension) but it worked.
Don't know if that helps you out, though.

Related

Getting HTML Source Code via XMLHttpRequest [JavaScript]

XMLHttpRequest works for first url but it doesn't work for second url.I think this function doesn't work for dynamic web pages.I also tried ajax to get html source but it didn't work too.What can I do?How can I change this code to work for second url?
<script language="Javascript" type="text/javascript">
function getSource(url)
{
var req = new XMLHttpRequest();
req.open(
"GET",
url,
true);
req.onreadystatechange = statusListener;
req.send(null);
function statusListener()
{
if (req.readyState == 4)
{
if (req.status == 200)
{
var doc=req.responseText;
alert(doc);
}
}
}
}
url1 = "https://pages.github.com/";
url2 = "https://stackoverflow.com/";
// This code WORKS
getSource(url1);
// This code DON'T WORK
getSource(url2);
</script>
I ran your code in a JSFiddle, and I got an error message saying it is a CORS issue. You can view these error messages by opening the Javascript console in your browser of choice.
CORS (Cross-Origin Resources Sharing) issues arise when you don't have the sufficient permission to access resources between different domains. Each web server has policies set up that determine the rules for accessing these files, and Stack Overflow's security settings are set up to disallow that kind of access to their site. You can read more about CORS here.

Changing path type causes ajax to fail?

I found this bizarre, but I recently change all my paths from relative to absolute.
I see that ajax appears to be working fine in the console as I can see the files retrieved successfully, with a status of 200.
Here is a pic: (its small but hopefully you can make out the status 200)
However, my callback functions stopped running, here is the code:
if (config_ajax.type === 'get') {
xhr = new win.XMLHttpRequest();
xhr.open('GET', config_ajax.url, true);
xhr.onload = function () {
if (this.status === 200) {
$A.log('succeeded with status 200'); // never gets here
config_ajax.callback(xhr.responseText);
}
};
xhr.send(null);
}
you have an incorrectly formatted request to the server as shown in firebug
http://www.arcmarks.com/http://www.arcmarks.com/arcmarks/source/class.CMachine.php
note the http://www shows twice
If the page is at arcmarks.com, it cannot make AJAX requests to www.arcmarks.com - browsers enforce something called the Same Origin Policy which prevents you from sending AJAX requests to any domain other than the exact one the original page was served from.
Also, the comment about the request being sent to www.www.arcmarks.com is right - as the code adds a "www" to the current URL, if your URL has a www in it already it will be repeated. But I'm assuming this was intentional.

using javascript to detect whether the url exists before display in iframe

I'm using javascript to pass a dynamic url to iframe src. but sometimes the url does not exist, how could i detect the non-exist url beforehand, so that i can hide the iframe that with 404 error.
Due to my low reputation I couldn't comment on Derek 朕會功夫's answer.
I've tried that code as it is and it didn't work well. There are three issues on Derek 朕會功夫's code.
The first is that the time to async send the request and change its property 'status' is slower than to execute the next expression - if(request.status === "404"). So the request.status will eventually, due to internet band, remain on status 0 (zero), and it won't achieve the code right below if. To fix that is easy: change 'true' to 'false' on method open of the ajax request. This will cause a brief (or not so) block on your code (due to synchronous call), but will change the status of the request before reaching the test on if.
The second is that the status is an integer. Using '===' javascript comparison operator you're trying to compare if the left side object is identical to one on the right side. To make this work there are two ways:
Remove the quotes that surrounds 404, making it an integer;
Use the javascript's operator '==' so you will be testing if the two objects are similar.
The third is that the object XMLHttpRequest only works on newer browsers (Firefox, Chrome and IE7+). If you want that snippet to work on all browsers you have to do in the way W3Schools suggests: w3schools ajax
The code that really worked for me was:
var request;
if(window.XMLHttpRequest)
request = new XMLHttpRequest();
else
request = new ActiveXObject("Microsoft.XMLHTTP");
request.open('GET', 'http://www.mozilla.org', false);
request.send(); // there will be a 'pause' here until the response to come.
// the object request will be actually modified
if (request.status === 404) {
alert("The page you are trying to reach is not available.");
}
Use a XHR and see if it responds you a 404 or not.
var request = new XMLHttpRequest();
request.open('GET', 'http://www.mozilla.org', true);
request.onreadystatechange = function(){
if (request.readyState === 4){
if (request.status === 404) {
alert("Oh no, it does not exist!");
}
}
};
request.send();
But notice that it will only work on the same origin. For another host, you will have to use a server-side language to do that, which you will have to figure it out by yourself.
I found this worked in my scenario.
The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callback methods introduced in jQuery 1.5 are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
$.get("urlToCheck.com").done(function () {
alert("success");
}).fail(function () {
alert("failed.");
});
I created this method, it is ideal because it aborts the connection without downloading it in its entirety, ideal for checking if videos or large images exist, decreasing the response time and the need to download the entire file
// if-url-exist.js v1
function ifUrlExist(url, callback) {
let request = new XMLHttpRequest;
request.open('GET', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('Accept', '*/*');
request.onprogress = function(event) {
let status = event.target.status;
let statusFirstNumber = (status).toString()[0];
switch (statusFirstNumber) {
case '2':
request.abort();
return callback(true);
default:
request.abort();
return callback(false);
};
};
request.send('');
};
Example of use:
ifUrlExist(url, function(exists) {
console.log(exists);
});
You could test the url via AJAX and read the status code - that is if the URL is in the same domain.
If it's a remote domain, you could have a server script on your own domain check out a remote URL.
Using async/await, this worked for me for opening a new tab; I needed to detect a 404 for the same reason as the OP:
openHelp : async function(iPossiblyBogusURL) {
const defaultURL = `http://guaranteedToWork.xyz`;
const response = await fetch(iPossiblyBogusURL);
if (response.status == 200) {
window.open(iPossiblyBogusURL, `_blank`);
} else if (response.status === 404) {
window.open(defaultURL, `_blank`);
}
},
You can try and do a simple GET on the page, if you get a 200 back it means the page exists. Try this (using jQuery), the function is the success callback function on a successful page load. Note this will only work on sites within your domain to prevent XSS. Other domains will have to be handled server side
$.get(
yourURL,
function(data, textStatus, jqXHR) {
//load the iframe here...
}
);
There is no need to make a separate HTTP request to check beforehand.
You could switch the logic around: only display the iframe if it has been loaded successfully. For this purpose, you can attach an onload event listener to the iframe.
See this related question for details: Capture iframe load complete event

How can I request a url using AJAX

I am quite new in this area.
I need to find out how to make a request to my solr server using Ajax
How can I give a url(my solr server's url) in request
Any body know how to deal with this?
How can i make a request to the below mentioned url
http://mysite:8080/solr/select/?q=%2A%3A%2A&version=2.2&start=0&rows=100&indent=on
See here: Corrected the Code Snippet as below
function getProductIds() {
var xmlhttp;
if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest();
else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) console.dir(xmlhttp);
else alert('no response');
var ajaxURL = "http://localhost:8080/solr/select/?q=*:*&version=2.2&start=0&rows=100&indent=on";
xmlhttp.open("GET", ajaxURL, true);
xmlhttp.send();
}
This is my code, it always showing "no response"
Thanks.
You will have to prepare the URL before sending in the request first get the URl using javascript and then encode it to ajax format like below
var URL = location.href;
var ajaxURL = encodeURIComponent(URL);
xmlhttp.open("GET",ajaxURL,true);
after reading your question clearly it seemed it is a static URL hence you can do below
var URL = "http://localhost:8080/blah blah blah";
xmlhttp.open("GET",URL,true);
Are you sure it is Get request. because get requests are most of the time cached. also log the response object into Firebug console and inspect the object to know more. Since you get no response that means the server did not send you anything for the request you made.
I'm just now working on XMLHttpRequests to solr as well and I was stuck with what seems like an identical problem. I too am quite new at this. However, the problem for me was that of same origin policy. Firefox seems to give very little feedback when this problem occurs. Chrome at least give you a error message (most of the time?).
In Chrome you can get around this, but only for development purposes, by starting it with the '--disable-web-security' command line option.
I'm yet to find a good workaround for this problem for Solr. In general you avoid the restriction by only using requests with relative paths, but that doesn't seem possible when doing a request to another port.
Ways to circumvent the policy (I haven't had time to study this too much yet)
$.ajax({
url: "url path",
context: document.body
}).done(function(data) {
alert(data);
});
This one also will work.

Prevent redirection of Xmlhttprequest

Is it possible to prevent the browser from following redirects when sending XMLHttpRequest-s (i.e. to get the redirect status code back and handle it myself)?
Not according to the W3C standard for the XMLHttpRequest object (emphasis added):
If the response is an HTTP redirect:
If the origin of the URL conveyed by the Location header is same origin
with the XMLHttpRequest origin and the
redirect does not violate infinite
loop precautions, transparently
follow the redirect while observing
the same-origin request event rules.
They were considering it for a future release:
This specification does not include
the following features which are being
considered for a future version of
this specification:
Property to disable following redirects;
but the latest specification no longer mentions this.
The new Fetch API supports different modes of redirect handling: follow, error, and manual, but I can't find a way to view the new URL or the status code when the redirection has been canceled. You just can stop the redirection itself, and then it looks like an error (empty response). If that's all you need, you are good to go. Also you should be aware that the requests made via this API are not cancelable yet. They are now.
As for XMLHttpRequest, you can HEAD the server and inspect whether the URL has changed:
var http = new XMLHttpRequest();
http.open('HEAD', '/the/url');
http.onreadystatechange = function() {
if (this.readyState === this.DONE) {
console.log(this.responseURL);
}
};
http.send();
You won't get the status code, but will find the new URL without downloading the whole page from it.
No you there isn't any place in the API exposed by XMLHttpRequest that allows you to override its default behaviour of following a 301 or 302 automatically.
If the client is running IE on windows then you can use WinHTTP instead to set an option to prevent that behaviour but thats a very limiting solution.
You can use responseURL property to get the redirect destination or check whether the response was ultimately fetched from a location you accept.
This of course means the result is fetched anyway, but at least you can get the necessary info about the redirect destination and for example detect conditions when you would like to discard the response.
I extended user's answer to include an abort() call. It seems like this prevents the server from sending too much data when all you want is the redirect url.
var url = 'the url'
var http = new XMLHttpRequest();
http.open('GET', url);
http.onreadystatechange = function() {
if (this.readyState === this.DONE) {
console.log(this.responseURL)
this.abort() // This seems to stop the response
}
}
http.send()
In real life I wrapped the above code in a promise, but it made the code hard to read.
Also, I don't understand why getting the redirect url needs to be this difficult, but that is a question for another time and place.
It is not possible to handle redirect or 302 status at client side as answered in other comments. However you can prevent redirection. To do that you can set request header "X-Requested-With" with "XMLHttpRequest"
xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
This should be done after open but before send. Example below
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
reqObj.success(JSON.parse(this.responseText))
} else if (this.status != 200) {
reqObj.error(this.statusText)
}
};
xhttp.open(reqObj.type, reqObj.url, reqObj.async);
xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhttp.send();

Categories