PHP跳转去除URL末尾#=问题:Facebook OAuth授权后重定向异常
解决Facebook OAuth认证后URL保留#=后缀的问题
这个问题我之前做OAuth集成时也碰到过,浏览器对URL锚点的处理确实有点“轴”——默认情况下,当服务器发送HTTP跳转头时,如果目标URL没指定锚点,它会把原URL的锚点原封不动地带过去。而Facebook OAuth回调里的#=属于锚点部分,这部分内容根本不会发送到服务器,所以你的后端完全不知道它存在,自然没法通过HTTP头跳转直接去掉它。
下面给你几个靠谱的解决办法,按推荐程度排序:
方法1:客户端JS强制清除锚点(最推荐)
在你的Facebook回调页面(也就是/authorize/facebook)里,加一段简单的JS代码,页面加载时自动检查并清除无用的锚点:
// 可以放在页面<head>的最前面,尽早执行 document.addEventListener('DOMContentLoaded', function() { if (window.location.hash === '#=') { // 用replace替换历史记录,避免用户后退时又回到带锚点的页面 window.location.replace(window.location.origin + '/'); } });
这段代码会在页面加载完成后检查当前URL的锚点,如果是#=就直接跳转到根目录,而且会替换掉当前的历史记录,体验上和服务器端跳转几乎没区别。
方法2:服务器端输出JS跳转页面
如果担心极少数用户禁用了JS(虽然现在这种情况几乎可以忽略),可以在后端处理完OAuth逻辑后,输出一个包含JS跳转的HTML页面,而不是用HTTP头跳转:
以PHP为例:
// 先完成Facebook OAuth的认证流程、获取用户信息等操作 // 然后输出跳转页面 ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>跳转中...</title> <script> // 立即执行跳转 window.location.replace('http://localhost:8000/'); </script> </head> <body> <!-- 给禁用JS的用户留个手动跳转入口 --> 页面正在自动跳转,如果没有反应,请<a href="http://localhost:8000/">点击这里</a> </body> </html> <?php exit;
这种方式下,JS会完全替换当前的URL(包括锚点部分),所以跳转后的URL绝对不会有#=。
方法3:服务器端跳转时指定空锚点(兼容性一般)
部分浏览器会尊重目标URL中的锚点设置,你可以试试在HTTP跳转头里加上空锚点:
header("Location: http://localhost:8000/#"); exit;
这样跳转后的URL会变成http://localhost:8000/#,虽然还有个空锚点,但比#=要干净。不过要注意,不是所有浏览器都吃这一套,所以优先级不如前两种方法。
内容的提问来源于stack exchange,提问作者Bruno Nunes
相关产品推荐
相关产品推荐

