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.
Related
I have a website, and I need a way to get html data from a different website via an http request, and I've looked around for ways to implement it and most say via an ajax call instead.
An ajax call is blocked by linked in so I want to try a plain cross domain http request and hope it's not blocked one way or another.
If you have a server running and are able to run code on it, you can make the HTTP call server side. Keep in mind though that most sites only allow so many calls per IP address so you can't serve a lot of users this way.
This is a simple httpListener that downloads an websites content when the QueryString contains ?site=http://linkedin.com:
// setup an listener
using(var listener = new HttpListener())
{
// on port 8080
listener.Prefixes.Add("http://+:8080/");
listener.Start();
while(true)
{
// wait for a connect
var ctx = listener.GetContext();
var req = ctx.Request;
var resp = ctx.Response;
// default page
var cnt = "<html><body>click me </body></html>";
foreach(var key in req.QueryString.Keys)
{
if (key!=null)
{
// if the url contains ?site=some url to an site
switch(key.ToString())
{
case "site":
// lets download
var wc = new WebClient();
// store html in cnt
cnt = wc.DownloadString(req.QueryString[key.ToString()]);
// when needed you can do caching or processing here
// of the results, depending on your needs
break;
default:
break;
}
}
}
// output whatever is in cnt to the calling browser
using(var sw = new StreamWriter(resp.OutputStream))
{
sw.Write(cnt);
}
}
}
To make above code work you might have to set permissions for the url, if you'r on your development box do:
netsh http add urlacl url=http://+:8080/ user=Everyone listen=yes
On production use sane values for the user.
Once that is set run the above code and point your browser to
http://localhost:8080/
(notice the / at the end)
You'll get a simple page with a link on it:
click me
Clicking that link will send a new request to the httplistener but this time with the query string site=http://linkedin.com. The server side code will fetch the http content that is at the url given, in this case from LinkedIn.com. The result is send back one-on-one to the browser but you can do post-processing/caching etc, depending on your requirements.
Legal notice/disclaimer
Most sites don't like being scraped this way and their Terms of Service might actually forbid it. Make sure you don't do illegal things that either harms site reliability or leads to legal actions against you.
Is there any way to get the http status of the current web page from javascript?
Spent some time searching on the web, but no luck at all... Seems like it's not possible, but wanted to check with Stack Overflow for maybe some fancy workaround.
(Providing it from the server as part of the response body is not acceptable, the status is supposed to be only available via the http header)
This is not in any way possible, sorry.
Yes You can
Simply request the same page, i.e. URI, using the XMLHttpRequest. Suppose that your page on /stop.php in stop.php you may do something like:
<script>
function xhrRequest(){
console.log(this.status);
// Do some logic here.
}
function getReq(url){
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", xhrRequest);
oReq.open("GET", url);
oReq.send();
}
getReq("/stop.php");
</script>
Checkout this DEMO
🕯 Note:
You have to note that, it is a copy of the page not the page itself.
I, already, have used this solution on a page in which the server may
generate Forbidden HTTP status code when the request is come from
unauthorized IP address, so the condition here is very simple and
there is no much difference between the original and the copy page
that you have simulate its visit.
As a one liner:
fetch(location.href).then(response => console.log(response.status));
This is asynchronous, if you need a synchronous solution use XMLHttpRequest (as in the other answer) together with async: false or use async/await which feels synchronous, but is still asynchronous under the hood.
Alternatively
An approach without an extra call would need to include the status code in the page on the server side (e.g. in a meta tag), then read it on the client side via JavaScript.
Java + Thymeleaf:
<meta name="statuscode" th:content="${#response.status}">
PHP (unverified):
<meta name="statuscode" content="<?php echo http_response_code() ?>">
It is not beautiful, but you can use:
t = jQuery.get(location.href)
.success(function () { console.log(t.status) })
.error(function() { console.log(t.status) });
That When Eric says, this solution will make a new request from the same paga, and not show status of current request.
you can only check status of page loading
try:var x = document.readyState;
The result of x could be:
One of five values:
uninitialized - Has not started loading yet
loading - Is loading
loaded - Has been loaded
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
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.
first of all, I want to thank miguel.de.icaza for this answer! Helped us a lot! But - here's the big BUT, here's our problem. In the UIWebView we start a "little" javascript App, created with SenchaTouch, that displays some charts. To give it a little look and feel, there's some interaction with the graphs. And sometime, we need to get some more data from the backend (e.g. for different chart types) using an AJAX request. But since the backend is saved with an self signed certificate, which doesn't work with the webView, as we know.
So, what we try to accieve is an AJAX request from our JS-app to the MonoTouch-App code, so that the Mono-app gets the data for the webview and passes it to a Javascript function, that updates the charts with the new data.
But as of right now, we're not able to get this to work, because as soon as we call the location.href = "app://get/chartData" we're logging a "about:blank" request, right before the "app://get/chartData" request, that - of course - blanks the webview and the current chart is gone. Using an simple AJAX request doesn't work for any reason. Meaning, the AJAX request doesn't call the ShouldLoadStart callback. Maybe, someone knows why?
Here's our MonoTouch code so far. This was just for testing the general workflow!! ;-)
NSUrl fileUrl = NSUrl.FromFilename("index.html");
NSUrlRequest req = new NSUrlRequest(fileUrl);
this.KPIWebView.LoadRequest(req);
this.KPIWebView.ShouldStartLoad = myHandler;
this.KPIWebView.LoadFinished += delegate {
indicator.StopAnimating ();
this.KPIWebView.Hidden = false;
};
bool myHandler(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navType)
{
Console.WriteLine(request.Url.ToString());
if(request.Url.ToString() == "about:blank")
{return false;} // doesn't help to avoid loading the "about:blank"
if(request.Url.ToString() == "ttl://data/salesGrowth/global")
{
string strData = Connection.Login("http://[yourIP/path]/salesGrowth/global");
return false;
try{
this.KPIWebView.EvaluateJavascript("Util.loadStoreData("+strData+")");
return false;
}
catch(Exception ex)
{ Console.WriteLine(ex.ToString()); }
return true;
} }
Any comments, ideas and help is greatly appreciated.
Thanks!
Edit:
After some more googleling I found out, that the thing with the about:blank request is a known issue with Senach Touch http://www.sencha.com/forum/showthread.php?123284-What-s-up-with-the-about-blank-page.
Finally, we were able getting it to run by using our own url schema: location.href = "app://action?jsCallback=MonoCallback&jsErrorCallback=ErrorCallback¶mName1=name1¶mVal1=value1&..."
In the webview.ShouldStartLoad callback, we're using the System.Uri namespace to check for the app protocol and to get all the parameters and javascript callback function names. Now we can do our request from within the mono-app. After all the action, we can call the jsCallback function with webview.EvaluateJavascript(jsCallback+"("+strValues+")");So, everything works fine now, even asynchronous!
Hope some of you, struggeling the same workflow issue with a self signed certificate within the webview, find this description helpful. If you have more questions about our "workaround" feel free to contact me.
Thanks!
I have a page with a dropdown. The onchange event calls a Javascript function (below) that includes an Ajax block that retrieves data and populates a TEXTAREA. On the surface, everything works.
I can select any item in the list with no problems. However, if I select an item that has previously been selected, the Ajax call appears to hang. It looks like maybe some weird caching issue or something. If I close the browser and reload the page, all items work again until I re-select.
I've tested for the readyState and status properties when it's hanging, but I get nothing. Am I missing something?
The page is a client project behind authentication so I can't post a URL, but here's the Ajax code. This is in a PHP page, but there's no PHP script related to this.
function getText( id ) {
var txt = document.getElementById( "MyText" );
txt.disabled = "disabled";
txt.innerText = "";
txt.className = "busy";
var oRequest = zXmlHttp.createRequest();
oRequest.open( "get", "get_text.php?id=" + id, true );
oRequest.send( null );
oRequest.onreadystatechange = function() {
if( oRequest.readyState == 4 ) {
if( oRequest.status == 200 ) {
txt.innerText = oRequest.responseText;
} else {
txt.innerText = oRequest.status + ": " + oRequest.statusText;
}
txt.disabled = "";
txt.className = "";
oRequest = null;
}
}}
Edit: The code block seems a little quirky; it won't let me include the final } unless it's on the same line as the previous.
You're setting the onreadystatechange function after you're sending the request. If it takes a long time (ie if it goes to the server), this will probably work, since there will be a delay before it tries to call the callback.
If the page is cached, though, the browser is probably trying to call onreadystatechange immediately in the send method. Move your assignment to onreadystatechange to before the open/send code.
HI,
The caching is due to the same url thats being called repeatedly. If you change the URl dynamically then this issue can be rsolved. Something like by adding a querystring with the current time with the request ( or any random renerated number ) you can change the url without affecting the result
I would guess that you are running into a caching issue. I have noticed that Internet Explorer is more aggressive at caching ajax calls than Firefox is. One way to be sure of what is happening is to use Fiddler2. This application monitors your web traffic, and you would be able to see if the browser is making a request or not, and what cache headers are coming back on the responses that you do get.
You can download fiddler2 from http://www.fiddlertool.com/fiddler/