Please, help me!
Can you explain me how to reload part of the page WITH change URL, but it must will not including hash tag.
some code:
URL: mysite.com/first/
<html>
<body>
<h1>RELOAD!</h1>
<div>few words...</div>
<input type="button">
<body>
</html>
want change to:
URL: mysite.com/second/
<html>
<body>
<h1>RELOAD!</h1>
<div>other few words...</div>
<input type="button">
<body>
</html>
How I can do reload content only in DIV on another?
I was see one more examples, like this next:
if (location.href.indexOf("#") > -1)
location.assign(location.href.replace('#', "/"));
BUT - it reload all page!
.htaccess - I cannot use, 'cause char "#" and next text not to sent to the server.
Also I have seen code:
history.pushState(null, null, '#myhash');
if(history.pushState) {
history.pushState(null, null, '#myhash');
}
else {
location.hash = '#myhash';
}
but cannot understand it right.
Maybe there is an other right way how to do it.
There are actually two different problems here:
How to load content from the server and display it in the existing page, without reloading the whole page
How to make it look like you are on a new URL, without reloading the page
Neither of these have anything to do with .htaccess (by which is generally meant Apache's mod_rewrite module) because they are both about how the client is behaving, not the server.
The first part is generally referred to as "AJAX", about which you will find tons of information online. The "X" originally stood for "XML", but actually you can fetch whatever kind of data you want, such as plain text, or a piece of ready-made HTML, and use JavaScript to put it into place on your page. The popular jQuery library has a method called .load(), which makes a request to the server, and uses the response to replace a particular part of the page.
The second part is a little trickier - since the page hasn't actually been reloaded, you essentially want the browser to lie about the current URL. The reason you will see a lot of examples changing only parts of the URL after the # is precisely because these aren't sent to the server; traditionally, they're used to scroll the current page to a paticular "anchor". You can therefore change them as often as you like, and if the user bookmarks or shares your page, you can look at the part after the # and re-load the state they bookmarked/shared.
However, as part of the "HTML5" group of technologies, an ability was added to change the actual URL bar of the browser, by "pushing a state" to the history object. In other words, adding an entry to the back/forward menu of the browser, without actually loading a new page. There are obvious security restrictions (you can't pretend the user navigated to a completely different domain), but the API itself is quite simple. Here is the MDN documentation explaining it.
For your simple example, assuming jQuery has been included, you might do something like this:
// Find the div with a jQuery selector; this would be more specific in reality
jQuery('div')
// Request some text from the server to replace the div
.load(
// This URL can be anything that generates the appropriate HTML
'/ajax.php?mode=div-content&stage=second',
// Add a callback function for when the AJAX call has finished
function(responseText, textStatus, XMLHttpRequest) {
// Inside the callback function, set the browser's URL bar
// and history to pretend this is a new page
history.pushState({}, '', '/second/');
}
);
Note that jQuery is far from the only way of doing this, it just keeps the example simple to make use of an existing function that does a lot of the work for us.
Related
Would it be possible to load an external page inside a container and replace text elements?
We work with ad campaigns and earn a percentage whenever a user signs up.
Can a script replace certain words? For instance “User” to “Usuario” or “Password” to “Contraseña” without affecting the original website or its functions.
Note: These links always pass through a redirection.
Example:
http://a2g-secure.com/?E=/0yTeQmWHoKOlN6zUciCXQwUzfnVGPGN&s1=
Note 2: Using an iframe is out of the question due to “Same-origin policy”.
I'm not sure if this answers your question, but you might find it useful.
(Perhaps you might give a step-by-step example of what you're trying to accomplish?)
If we assume that a browser attempts to retrieve page P from a proxy which first retrieves the content of page P from its actual home and then performs some transformation on its content before returning that page content to the browser, what you're describing is a Reverse HTTP Proxy and is a very well-known page serving technique.
Rather than performing complex transformations at the server (which require specialized knowledge of the page layout), this technique is usually used to inject a single line into the retrieved source that calls a JavaScript file to actually perform the required transformation at the browser.
So in essence:
Browser requests Page P from Proxy 1.
Proxy 1 retrieves the actual Page P from its real home, Server 2.
Proxy 1 adds the line <script src="//proxy1.com/transform.js"></script> to the source of Page P.
Proxy 1 then returns the modified source of Page P to Browser.
Once the Browser has received the page content, the JavaScript file is also retrieved, which can then modify the page contents in any way required.
This technique can be used to solve your "Same origin policy" issue by loading an iframe from a URL that points to the same server as that which provided the parent or owning page of the iframe which acts as proxy, like:
http://example.com/?proxy_target=//server2.com/pageP.html
Thus, the browser only "sees" content from a single server.
You would need to load the external page server-side, and then you can do whatever you want with it. You can do serverside string replacement, or you can do it later in javascript.
But, remember that as soon as you add a whole webpage into for example a div in your own page, the css from your page will affect it.
Plus, you would need to manipulate all the links in the documents, to have absolute urls. If the page depends on ajax, there is pretty much no way to accomplish what you want to do.
If on the other hand the pages you will be loading are static html, it is possible, though there are a lot of things you need to take care of before you can actually present the page to the user, like adjusting links, urls to stylesheets and so on.
It seems you are trying to localize a website on the fly, using your server as a proxy for that content. Does it make sense? If that's the case, depending on the size of your operation, there are several proxy translation services out there (I'll name them if needed).
Basically, they scrape a website, providing a way for you to translate and host the translated content. Of course, this depends on your relationship with the content providers. You should also take this into consideration, since modifying content, even for translation, can be a copyright problem.
All things considered, if you trust the provider's javascript, the solution involves scraping the content, as mentioned in other answers, and serving that modified content. You really need to trust the origin...
update per request
http://www.easyling.com
http://www.smartling.com
http://www.motionpoint.com
http://www.lionbridge.com/solutions/translation-proxy/
http://www.sajan.com/translation-proxy-technology-and-traditional-website-translation-understanding-your-options/
They are all aimed at enterprise-grade projects, but I would say Easyling is the most accessible.
Hope this helps.
Using the .load() callback function, this will replace the text
$(function(){
$("#Content").load("http://example.com?user=Usuario",function() {
$(this).html($(this).html().replace("user", +get param value+));
});
redirection u can use
// similar behavior as an HTTP redirect
window.location.replace("url");
// similar behavior as clicking on a link
window.location.href = "url";
The answer is NO, not without using a server-side proxy. For a really good overview of how to use a proxy, see this YUI page: https://developer.yahoo.com/javascript/howto-proxy.html (Be patient, as it will take time to load, but the illustrations are worth it!)
When I try to do this in jsfiddle to see what data that the 3 parameters contain, then the error below appears:
$(function() {
$(this).load('https://stackoverflow.com/questions/36003367/load-external-page-and-replace-text', function(responseText, textStatus, jqXHR){
debugger;
});
});
ERROR:
XMLHttpRequest cannot load Load external page and Replace text.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.
I'm working on a website that uses AJAX loading with some jQuery animations.
With JavaScript, I grab the href from a dynamically generated link to a PHP-based page, and then add that href to URL (after the inevitable #/) .
So far so good, except if a user bookmarks the page and tries to access it, that user will arrive to the home page, instead of the page he/she expected to access.
So, when a page is accessed directly, not by clicking on the internal link of the website, I want to remove #/ from the url, but keep everything after it, so that URL that was bookmarked like this:
http://www.mysite.com/#/somepage
gets rewritten as this:
http://www.mysite.com/somepage
THEN, after the proper page ( http://www.mysite.com/somepage ) finished loading, I want to stick #/ back into its former place in URL ( http://www.mysite.com/#/somepage ), without reloading the page (which, thanks to a clever snippet I'm using, will ensure that the rest of the navigation works the way it should.)
So:
Before page loads, check URL and if it has #/, remove it.
Load page located at hash-less url
Redisplay the url with #/, without reloading the page.
Is it even doable? If yes, I'd be grateful for a lesson.
What you are trying to do is doable but an utter PITA to maintain, and it will not be available on all browsers. That aside, the key resides in the history object relatively recently extended to add a new set of "tricks". Its full doc is available from MDN.
What you are after to do this is the replaceState command. Reads as follows:
Updates the most recent entry on the history stack to have the specified data, title, and, if provided, URL. The data is treated as opaque by the DOM; you may specify any JavaScript object that can be serialized. Note that Firefox currently ignores the title parameter; for more information, see manipulating the browser history.
This will allow you to replace your current page in the history of the browser, but not in the URL. The URL will be exactly as you have it - with the hash. No point changing it considering your solution.
However, you will have to make sure that your hashless page redirects to the hash-present page for clients with the history object, for consistency. That's the only requirement.
Before page loads, check URL and if it has #/, remove it.
Not possible. The fragment id is not sent to the server, so you can only access it with client side code and that requires the page to load (or at least to start loading).
Load page located at hash-less url
Redisplay the url with #/, without reloading the page
Use XMLHttpRequest to get the data, DOM to change the document to use it, and the history API to change the URL in the address bar.
As has been pointed out in one of the answers, you can't remove hash before your page loads.
However, once the page started loading, the manipulation described in the question is possible.
Here's one way to do it.
// Remove the hash and reload the page at url without hash
if (window.location.href.indexOf('/#/')>=0) {
window.location = window.location.href.replace(/\/#\//, '/');
}
Once the new page started loading, you can use history.pushState to update the URL display:
if ((window.location.href.indexOf('/#/')<1) && (location.pathname != "/")) {
history.pushState({}, "page x", location.protocol + '//' + location.host + '/#' + location.pathname);
}
You gotta keep in mind though that pushState is only available for browsers started with Gecko 2.0, so placing the hash back into the url will not work in older browsers, period.
This may lead to some unfortunate situations. For example, hypothetically, your url http://www.mywebsite.com/somepage gets indexed by a search engine. A user clicks on that link, accessing your website in an older browser that doesn't support pushState, and then clicks on some other link when browsing your AJAX-enabled website. That user is likely to arrive to
http://www.mysite.com/somepage/#/someotherpage
And then, as the user keeps clicking, it will only keep getting worse:
http://www.mysite.com/somepage/#/someotherpage/#/yetanotherpage/#/andsoon/#/andsoforth/
So what you probably need is something to make sure that your hashes don't keep propagating.
You can also wrap your hash removing / replacing code in a conditional:
if (history.pushState) {
// add hash
} else {
// provide some alternative
}
Finally, look into these two resources. You may not need the hash at all: History.js and jQuery Address.
Ok, so all the rage these days is having a site like this:
mysite.com/
mysite.com/about
mysite.com/contact
But then if the user has Javascript enabled, then to have them browse those pages with Ajax:
mysite.com/#/
mysite.com/#/about
mysite.com/#/contact
That's all well and good. I have that all working perfectly well.
My question is, if the user arrives at "mysite.com/about", I want to automatically redirect them to "mysite.com/#/about" immediately if they have Javascript.
I have it working so if they arrive at "mysite.com/about", that page will load fine on its own (no redirects) and then all clicks after that load via ajax, but the pre-fragment URL doens't change. e.g. if they arrive on "mysite.com/about" and then click "contact", the new URL will be "mysite.com/about#/contact". I really don't like that though, it's very ugly.
The only way I can think of to automatically redirect a user arriving at "mysite.com/about" to "mysite.com/#/about" is to have some javascript in the header that is ONLY run if the page is NOT being loaded via ajax. That code looks like this ($ = jQuery):
$(function(){
if( !location.hash || location.hash.substr(1,1) != '/' ) {
location.replace( location.protocol+'//'+location.hostname+'/#'+location.pathname+location.search );
}
});
That technically works, but it causes some very strange behavior. For example, normally when you "view source" for a page that has some ajax content, that ajax content will not be in the source because you're viewing the original page's source. Well, when I view source after redirecting like this, then the code I see is ONLY the code that was loaded via Ajax - I've never seen anything like that before. This happens in both Firefox 3.6 and Chrome 6.0. I haven't verified it with other browsers yet but the fact that two browsers using completely different engines exhibit the same behavior indicates I am doing something bad (e.g. not just a bug with FF or Chrome).
So somehow the browser thinks the page I'm on "is" the Ajax page. I can continue to browse around and it works fine, but if I e.g. close Firefox and re-open it (and it re-opens the pages I was on), it only reloads the Ajax fragment of the page, and not the whole wrapper, until I do a manual refresh. (Chrome doesn't do this though, only Firefox). I've never seen anything like that.
I've tried using setTimeout so it does not do the redirect until after the page has fully loaded, but the same thing happens. Basically, as far as I can tell, this only works if the fragment is put there as the result of a user action (click), and not automatically.
So my question is - what's the best way to automatically redirect a Javascript capable browser from a "normal" URL to an Ajax URL? Anyone have experience doing this? I know there are sites that do this - e.g., http://rdio.com (a music site). No weirdness happens there, but I can't figure out how they're doing it.
Thanks for any advice.
This behavior is like the new twitter. If you type the URL:
http://twitter.com/dinizz
You will be redirected to:
http://twitter.com/#!/dinizz
I realize that this is done, not with javascript but in the server side. I am looking for a solution to implements this using ruby on rails.
Although I suggest you to take a look on this article: Making AJAX Applications Crawlable
How to automatically replace url in browser address bar with JavaScript
from company.com/en/services/
to company.com/en/#services
?
Example: when I type in browser address bar url company.com/en/services/ and click 'Go', it will be automatically seen company.com/en/#services
Is there any way to replace real url /services/ with hash url /#services without browser refresh and no redirecting? Does jQuery has some solution for that?
You can't change the URL with Javascript for the current page. You can only change the hash like this (without causing a refresh):
window.location.hash = '#services';
So when you're at the page company.com/en/ and then click something, you could then set the window.location.hash. For example, it could be changed to company.com/en/#anything_you_set. The only other way is to do what Pekka suggested and reload the page.
If you want them to type the url and have it change to the hash, you're going to have to look up URL Rewriting (at least for ASP.NET and IIS). If you're on IIS7, you can use the URL Rewrite Module.
If you're on apache, you can read this URL rewrite tutorial.
You could do something like this:
$(document).ready(function() {
window.document.location.href = 'company.com/en/#services'
});
I'd go with:
<script>
document.replace("/en/#services");
</script>
<meta http-equiv="refresh" content="0;url=/en/#services" />
on /en/services/
Document.replace(url) will have the browser load the new page, and the old one won't be in the history, so when the user hits back, they won't get stuck in loop. The meta catches people without JS.
I don't think that you can't reliably do this with a server-side redirect, as many browsers (and the HTTP spec) consider the hash client-side only, and so it doesn't survive the redirect.
I found the solution in http://www.asual.com/jquery/address/.
I have a html page on my localhost - get_description.html.
The snippet below is part of the code:
<input type="text" id="url"/>
<button id="get_description_button">Get description</button>
<iframe id="description_container" src="#"/>
When the button is clicked the src of the iframe is set to the url entered in the textbox. The pages fetched this way are very big with lots of linked files. What I am interested in the page is a block of text contained in a <div id="description"> element.
Is there a way to mitigate downloading of resources linked in the page that loads into the iframe?
I don't want to use curl because the data is only available to logged in users and the steps to take with curl to get the content is too complicated. The iframe is simple as I use this on a box which sends the right cookies to identify the request as coming from a logged in user, but the problem is that it is very wasteful to get nearly 1 MB of data to keep 1 KB of it and throw out the rest.
Edit
If the proposed method just works in Firefox it is fine, so I added Firefox tag. Also, it is possible that the answer actually is from the realm of Firefox add-on techniques, so I added that tag as well.
The problem is not that I cannot get at what I'm looking for, rather, the problem is the easy iframe method is wasteful.
I know that Firefox does allow loading only the text of a page. If you open a page and press Ctrl+U you are taken to 'view page source' window, There links behave as normal and are clickable, if you click on a link in source view, the source of the new page is loaded into the view source window, without the linked resources being downloaded, exactly what I'm trying to get. But I don't know how to access this behaviour.
Another example is the Adblock add-on. It somehow kills elements before they get loaded. With plain Javascript this is not possible. Because it only is triggered too late to intervene in good time.
The Same Origin Policy forbids any web page to access contents of any other web page in a different domain so basically you cannot do that.
However it seems that with some browsers it is allowed to access web pages content if you are trying to access it from a local web page which seems to be your case.
Safari, IE 6/7/8 are browser that allow a local web page to do so via XMLHttpRequest (source: Google Browser Security Handbook) so you may want to choose to use one of those browsers to do what you need (note that future versions of those browsers may not allow to do so anymore).
A part from this solution I only see two possibities:
If the web pages you need to fetch content from are somehow controlled by you, you can create a simpler interface to let other web pages to get the content you need (for example allowing JSONP requests).
If the web pages you need to fetch content from are not controlled by you the only solution I see is to fetch content server side logging in from the server directly (I know that you don't want to do so, but I don't see any other possibility if the previous I mentioned are not practicable)
Hope it helps.
Actually I've seen Cross Domain jQuery .load request before, here: http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
The author claims that codes like these found on that page
$('#container').load('http://google.com'); // SERIOUSLY!
$.ajax({
url: 'http://news.bbc.co.uk',
type: 'GET',
success: function(res) {
var headline = $(res.responseText).find('a.tsh').text();
alert(headline);
}
});
// Works with $.get too!
would work. (The BBC code might not work because of the recent redesign, but you get the idea)
Apparently it is using YQL wrapped into a jQuery plugin to do the trick. Now I cannot say I fully understand what he is doing there but it appears to work, and fits the bill. Once you load the data I suppose it is a simple matter of filtering out the data that you need.
If you prefer something that works at the browser level, may I suggest Mozilla's Jetpack framework for lightweight extensions. I've not yet read the documentations in its entirety but it should contain the APIs needed for this to work.
There are various ways to go about this in AJAX, I'm going to show the jQuery way for brevity as one option, though you could do this in vanilla JavaScript as well.
Instead of an <iframe> you can just use a container, let's say a <div> like this:
<div id="description_container"></div>
Then to load it:
$(function() {
$("#get_description_button").click(function() {
$("#description_container").load($("input").val() + " #description");
});
});
This uses the .load() method which takes a string in this format: .load("url selector"), then takes that element in the page and places it's content inside the container you're loading, in this case #description_container.
This is just the jQuery route, mainly to illustrate that yes, you can do what you want, but you don't have to do it exactly like this, just showing the concept is getting what you want from an AJAX request, rather than in an <iframe>.
Your description sounds like you are fetching pages from the same domain (you said that you need to be logged in and have session credentials) so have you tried to use async request via XMLHttpRequest? It might complain if the html on a page is particularly messed up but you chould still be able to get raw text via .responseText and extract what you need with a regex.