I am trying to get the content of a 404 custom page via ajax (Ii need a counter value at this page using Greasemonkey).
Unfortunately jQuery's .fail method of ajax does not give a possibility to actually read the contents of the page like the data value on success.
Is there any workaround? I will also buy vanilla js.
Best rehards
You may do this in Vanilla JS :
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4) {
console.log(httpRequest.responseText);
}
};
pmc.loading.start();
httpRequest.open('GET', url);
httpRequest.send();
Ajax's error callback can be used too :
$.ajax({
url: url,
error: function(httpRequest){
console.log(httpRequest.responseText);
}
});
This being said, I wonder, from your comments, if you're not subject to problems related to same origin policy : you can't read in javascript the content of a page issued from another domain if the site's owner didn't put the right headers.
If that's the case, you can't do anything purely client-side without the consent of the site owner. The easiest would be to add a proxy on your site to serve the page as if it was coming from your site.
Related
I'm struggling with stabilizing Selenium automation for jQuery/AJAX application hence referred to
https://www.swtestacademy.com/selenium-wait-javascript-angular-ajax/
and it has ajaxComplete() method which has following code -
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open('GET', '/Ajax_call', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send();
);
I haven't work on JavaScript before and this code which I'm not able to understand completely. I've following questions with this, if someone can help to understand it -
What is Ajax_call in this? Is it generic call to check ajax completion? Or do I need to have my own endpoint there? If yes, does single end point enough or do I need to identify all calls and add them in the method?
Please check the documentation for XMLHttpRequest.open. If you do, you will the second argument listed is
url
A DOMString representing the URL to send the request to.
This means that it is simply the URL you want to request. I can be anything you want. The / prefix means that you are request relative to the root of the website (so if you are requesting from https://example.com/somedir/somepage the request will be made to https://example.com/Ajax_call.
I have a web page that has a too much content and javascript. When the page loads it makes multiple requests using Ajax and XMLHttp to load data. Is there a way to hook up all these requests and direct them to a different server.
For example the webpage fetches data from www.apple.com/data and www.mango.com/data after it is loaded. Is is possible to insert a script somewhere in the webpage which automatically changes any request made to www.orange.com/data.
Waiting for answer. Thanks
You can add a global handler to the ajaxSend event, the event will be triggered right before the ajax request being sent out. So you can check the request uri, apply some filtering logic, and then redirect the request by abort the original and resend it.
Below is an example
$(document).ajaxSend(function(e, xhr, opt) {
if (opt.url.indexOf("www.apple.com") !== -1) {
// abort the request
xhr.abort();
// change the uri to www.orange.com
opt.url = opt.url.replace("www.apple.com", "www.orange.com");
$.ajax(opt);
}
});
Ok. So I followed Anthony C's answer and it did actually work. But the problem with his solution is that it only works with Ajax requests not XMLHttpRequests (I am not sure why, I am a beginner at this topic.) However digging on his idea of creating a hook I came across a similar post here How to get the URL of a xmlhttp request (AJAX). The code provided a way to fetch the requested URL for each request. So by a little tweak to the code I managed to come up with this:-
XMLHttpRequest.prototype.open = (function(open) {
return function(method,url,async) {
var uri=getLocation(url);// use get location function to convert requested url string into readable url
if(uri.hostname!="orange.com"){
url="https://orange.com" + url;
}
open.apply(this,arguments);
};
})(XMLHttpRequest.prototype.open);
var getLocation = function(href) {
var l = document.createElement("a");
l.href = href;
return l;
};
This code at top of the page allows me to change the host name of all XMLHttpRequests that are not directed towards orange.com. Though I am sure there are better ways to write this code as well but since I am not an expert over javascript this will suffice my need for the time.
I would like to know if it is possible in JavaScript to access to a given URL without opening its web page in a browser . Actually, what I'm really trying to do is parsing through a page (given its URL) and clicking on the first link that it contains without even opening that web page in my browser. Is that doable with JavaScript. In case it is, how should I do that? What function (or functions) should I use? In case it is not, what would the alternative solutions be?
What you need is to make an HTTP request to the URL and process the results. You can do that in JavaScript using the XMLHttpRequest object. Example:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
};
xhttp.open("GET", "put_the_URL_here", true);
xhttp.send();
However, it is easier to use a library like jQuery.Ajax for that:
$.ajax({
url: "put_the_URL_here",
context: document.body
}).success(function(data) {
console.log(data);
});
For this to work, the URL that you're trying to access must have CORS enabled.
I am dynamically loading a widget from another webservice that requires a script to be run immediately after it. The example uses document.write() to do this, but this does not work because it doesn't run until after the document has been closed, which means it overwrites the entire document. I am trying to load it via AJAX using pure JavaScript:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) { // success
eval(this.responseText);
}
};
xhttp.open("GET", "https://d3gxy7nm8y4yjr.cloudfront.net/js/embed.js", true);
xhttp.setRequestHeader('Content-type', 'application/javascript');
xhttp.send();
but I get the following error:
XMLHttpRequest cannot load
https://d3gxy7nm8y4yjr.cloudfront.net/js/embed.js. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://example.com' is therefore not allowed
access.
I was able to make it work using jQuery on my test server with this code:
$.ajax({
dataType: "script",
cache: true,
url: "https://d3gxy7nm8y4yjr.cloudfront.net/js/embed.js"
});
However, I cannot use jQuery on my production server because... well... work politics.
How is jQuery accomplishing this without an error, and how can I do it in pure JavaScript?
Solution
As stated by #shabs, $.ajax adds a script tag to the document.head and then immediately removes it. I checked this by adding a breakpoint and saw it added and removed in Chrome's inspector. It appears to remove the file as soon as the current script completes regardless of what the file is. This works well for immediately invoked scripts, but I don't know how this would work with something like a library.
For a pure JavaScript implementation I used the following code:
var widgetScript = document.createElement("script");
widgetScript.async = true;
widgetScript.src = "https://d3gxy7nm8y4yjr.cloudfront.net/js/embed.js";
document.head.append(widgetScript);
widgetScript.remove();
The resource in question doesn't support CORS.
This works through $.ajax because when you specify dataType: "script", jQuery actually appends a <script> tag to document.head! *
Is there a particular reason you're not just using something like <script type="text/javascript" src="https://d3gxy7nm8y4yjr.cloudfront.net/js/embed.js"></script>?
* (This is news to me! The documentation for $.ajax mentions that "script [...] requests are not subject to the same origin policy restrictions", and the source code confirms this.)
I'm currently experimenting with replacing a number of function I currently use jQuery for with a Vanilla Javascript alternative. This is to:
Increase my understanding of JavaScript as a whole
Make me a better front-end developer (ties into the above)
Improve the speed and responsiveness of my web applications by negating the need for a library such as jQuery for simple tasks.
My aim today is to produce a JavaScript function that allows me to make an Ajax call to another site to retrieve a specific Div and use the content from that Div within my page. I can do this pretty easily with jQuery by filtering the response from an Ajax call with the .find() method to retrieve the specific Div I require then use the .html() function to strip the content and append it to the Div on my site. However, I cannot see an alternative method of doing this using Vanilla JavaScript.
My code so far can be found below:
function fireAjaxRequest(requestType,requestUrl,contentPlaceholder){
var ajaxRequest;
if(window.XMLHttpRequest){
ajaxRequest = new XMLHttpRequest();
}else{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4 && ajaxRequest.status == 200){
contentPlaceholder.innerHTML = ajaxRequest.responseText;
}
}
ajaxRequest.open(requestType,requestUrl, true);
ajaxRequest.send();
}
I call my function as follows:
var contentArea = document.getElementById('news');
fireAjaxRequest('GET', 'http://www.bbc.co.uk',contentArea);
When I load my page, I can see in Firebug that the request completes successfully and I get
a 200 Success response from the Ajax call however, nothing is displayed in my target element. At first I thought this was because you cannot store a whole page within a single element but after altering my code slightly I found the the following snippet of code does not seem to be executed upon the success of the Ajax call:
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4 && ajaxRequest.status == 200){
contentPlaceholder.innerHTML = ajaxRequest.responseText;
}
}
Am I doing something incorrectly here?
You really need to look into XSS. I think you'll understand why there are serious restrictions with what you're trying to do.
If you control both domains, you can use JSONP or CORS.
You could also write send an ajax request to your own server that acts as a proxy. Your server would "forward" the request to the destination server, and relay the response to the client.