在浏览器中更改url,而不使用JavaScript加载新页面
我怎么会有一个JavaScript的行动,可能对当前页面有一些影响,但也将更改浏览器中的URL,所以如果用户点击重新加载或书签新的URL使用?
如果后退button将重新加载原始URL,这也会很好。
我正在尝试在URL中loggingJavaScript状态。
如果您希望它在不支持history.pushState
和history.popState
浏览器中工作,“旧”方法是设置片段标识符,这将不会导致页面重新加载。
基本思想是将window.location.hash
属性设置为一个包含所需状态信息的值,然后使用window.onhashchange事件 ,或者对于不支持onhashchange
旧浏览器(IE <8,Firefox < 3.6),定期检查哈希是否已经改变(例如使用setInterval
)并更新页面。 您还需要在页面加载时检查散列值以设置初始内容。
如果你使用的是jQuery,那么就有一个hashchange插件 ,它将使用浏览器支持的任何方法。 我确定也有其他库的插件。
需要注意的一件事是与页面上的id相冲突,因为浏览器将滚动到具有匹配id的任何元素。
使用HTML 5,请使用history.pushState
函数 。 举个例子:
<script type="text/javascript"> var stateObj = { foo: "bar" }; function change_my_url() { history.pushState(stateObj, "page 2", "bar.html"); } var link = document.getElementById('click'); link.addEventListener('click', change_my_url, false); </script>
和一个href:
<a href="#" id='click'>Click to change url to bar.html</a>
如果您想更改URL而不添加条目到后退button列表,请改为使用history.replaceState
。
window.location.href包含当前的URL。 你可以从中读取,你可以附加到它,你可以replace它,这可能会导致页面重新加载。
如果,因为它听起来像,你想要logging的JavaScript状态的URL,所以它可以被书签,而无需重新加载页面,追加到#后的当前URL,并有一段由onload事件触发的javascriptparsing当前URL来查看它是否包含保存的状态。
如果你使用? 而不是一个#,你会强制重新加载页面,但由于你将parsing加载时保存的状态,这可能不是一个问题; 这将使前进和后退button正常工作。
我强烈怀疑这是不可能的,因为如果是这样,那将是一个难以置信的安全问题。 例如,我可以创build一个看起来像银行login页面的页面,并使地址栏中的URL看起来像真正的银行 !
也许如果你解释为什么你想这样做,人们可能会build议替代方法…
[编辑于2011年:自从2008年我写了这个答案以来,更多的信息已经被发现,关于HTML5技术 ,允许URL被修改,只要它来自同一个来源]
浏览器安全设置可以防止用户直接修改显示的url。 您可以想象会导致的networking钓鱼漏洞。
只有在不改变页面的情况下更改url的可靠方法是使用内部链接或散列。 例如: http : //site.com/page.html变成http://site.com/page.html#item1 。 这种技术经常用在hijax(AJAX +保存历史logging)中。
当我这样做的时候,我会经常使用哈希作为href的操作链接,然后用jquery添加点击事件,使用请求的哈希来确定和委托操作。
我希望能让你走上正确的道路。
jQuery有一个很棒的插件来改变浏览器的URL,叫做jQuery-pusher 。
JavaScript pushState
和jQuery可以一起使用,如:
history.pushState(null, null, $(this).attr('href'));
例:
$('a').click(function (event) { // Prevent default click action event.preventDefault(); // Detect if pushState is available if(history.pushState) { history.pushState(null, null, $(this).attr('href')); } return false; });
只使用javascript history.pushState()
,它会更改引用链接,它将在更改状态后创build的XMLHttpRequest对象的HTTP标头中使用。
例:
window.history.pushState("object", "Your New Title", "/new-url");
pushState()方法:
pushState()
有三个参数:一个状态对象,一个标题(当前被忽略)和(可选)一个URL。 让我们来更详细地检查这三个参数中的每一个:
-
状态对象 – 状态对象是与由
pushState()
创build的新历史logging条目相关联的JavaScript对象。 只要用户导航到新的状态,就会触发一个popstate事件,事件的state属性包含历史logging的状态对象的副本。状态对象可以是任何可以序列化的东西。 由于Firefox会将状态对象保存到用户的磁盘中,以便在用户重新启动浏览器之后可以恢复它们,所以我们在状态对象的序列化表示上强加了一个640k字符的大小限制。 如果你传递了一个状态对象的序列化表示大于这个
pushState()
,该方法将抛出一个exception。 如果您需要更多的空间,build议您使用sessionStorage和/或localStorage。 -
标题 – Firefox目前忽略这个参数,虽然它可能在将来使用它。 在这里传递空string应该对将来对方法的更改是安全的。 或者,您可以通过一个简短的标题为您正在移动的状态。
-
URL – 新的历史logging的URL由此参数给出。 请注意,在调用
pushState()
之后,浏览器将不会尝试加载此URL,但可能会在稍后尝试加载URL,例如用户重新启动浏览器之后。 新的URL不需要是绝对的; 如果它是相对的,则相对于当前URLparsing。 新的url必须与当前url的来源相同; 否则,pushState()
会抛出exception。 该参数是可选的; 如果未指定,则将其设置为文档的当前URL。
有一个雅虎YUI组件(浏览器历史loggingpipe理器),可以处理这个: http : //developer.yahoo.com/yui/history/
Facebook的照片库使用URL中的#hash来执行此操作。 以下是一些示例url:
点击“下一步”之前:
/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507
点击“下一步”后:
/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507
注意紧跟着新URL的哈希(#!)。
有一个jQuery插件http://www.asual.com/jquery/address/
我认为这是你所需要的。
我的代码是:
//change address bar function setLocation(curLoc){ try { history.pushState(null, null, curLoc); return false; } catch(e) {} location.hash = '#' + curLoc; }
和行动:
setLocation('http://example.com/your-url-here');
和例子
$(document).ready(function(){ $('nav li a').on('click', function(){ if($(this).hasClass('active')) { } else { setLocation($(this).attr('href')); } return false; }); });
就这样 :)
我想知道只要页面中的父path是相同的,只有新的东西被添加到它。
所以,就像我们说的用户在页面: http://domain.com/site/page.html
: http://domain.com/site/page.html
那么浏览器可以让我做location.append = new.html
和页面变成: http://domain.com/site/page.htmlnew.html
: http://domain.com/site/page.htmlnew.html
和浏览器不会改变它。
或者只是让人们改变get参数,所以让我们location.get = me=1&page=1
。
所以原来的页面变成http://domain.com/site/page.html?me=1&page=1
,它不刷新。
#的问题是,当哈希被改变时,数据没有被caching(至less我不这么认为)。 所以这就像每次加载新页面一样,而非Ajax页面中的后退和前进button能够caching数据,而不用花时间重新加载数据。
从我看到的,雅虎的历史事物已经加载所有的数据一次。 它似乎没有做任何Ajax请求。 所以当一个div
用来处理不同的方法超时时,这个数据不会被存储在每个历史状态中。
我已经成功:
location.hash="myValue";
它只是将#myValue
添加到当前的URL。 如果您需要在页面加载中触发事件,则可以使用相同的location.hash
来检查相关的值。 只记得从location.hash
返回的值中删除#
例如
var articleId = window.location.hash.replace("#","");