首页 » 杂项 » 一段js引发的血案 --IE js 新窗口跳转 问题

一段js引发的血案 --IE js 新窗口跳转 问题

 

今天踩了一个非常刁钻的坑

前面给凤凰对接
由于第三方支付连连支付
只允许从我们公司域名发起支付请求

所以
从我们域名给凤凰提供了一个中转跳板
p.php

<?
//获取url 链接
//***********
$url="https://llpay.com?xxxxx=xxx&xxx=xx";
$checkurl=parse_url($url);
if (!$checkurl['scheme'] || !$checkurl['host']) {
// p( parse_url($url));
die('err URL');
}

$query=$checkurl['query'];
$urlarr=array();
$url2= http_build_query($urlarr);
$url3=$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'?'.$url2;
parse_str($checkurl['query'],$urlarr);

//测试使用header跳转,发现连连会提示
//出错了!
//商户域名未报备,请联系客服处理[1006][商户唯一单号:xxxxxxxxxxxxxxxx]
// header('Location: '.$url ,TRUE,301);

//跳转至支付平台
echo '<script type="text/javascript">var url=\''.$url.'\';window.location.href=url; </script>';

测试下来
chrome、360浏览器 连连支付 均可以正常识别

IE从此页面跳转至 连连支付时
再次出现 商户域名未报备 提示

初步判断可能会是IE传递querystring时候问题,于是

有了以下代码
<?
//获取url 链接
//***********
$url="https://llpay.com?xxxxx=xxx&xxx=xx";
$checkurl=parse_url($url);
if (!$checkurl['scheme'] || !$checkurl['host']) {
// p( parse_url($url));
die('err URL');
}

$query=$checkurl['query'];
$urlarr=array();
$url2= http_build_query($urlarr);
$url3=$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'?'.$url2;
parse_str($checkurl['query'],$urlarr);

//测试使用header跳转,发现连连会提示
//出错了!
//商户域名未报备,请联系客服处理[1006][商户唯一单号:xxxxxxxxxxxxxxxx]
// header('Location: '.$url ,TRUE,301);

//跳转至支付平台
echo '<script type="text/javascript">var url=\''.$url.'\';window.location.href=url; </script>';

结果令人失望 依旧提示未报备
甘老师建议可以尝试使用form 跳转
于是有了以下尝试

<?
//获取url 链接
//***********
$url="https://llpay.com?xxxxx=xxx&xxx=xx";
$checkurl=parse_url($url);
if (!$checkurl['scheme'] || !$checkurl['host']) {
// p( parse_url($url));
die('err URL');
}

$query=$checkurl['query'];
$urlarr=array();
$url2= http_build_query($urlarr);
$url3=$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'?'.$url2;
parse_str($checkurl['query'],$urlarr);

if(strpos($_SERVER['HTTP_USER_AGENT'],"MSIE")) {
echo '<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body onload="javascript:document.pay_form.submit();">';
echo ' <form id="pay_form" name="pay_form" method="get" target="_blank" action="'.$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'" >';
foreach ($urlarr as $k => $v)
{
echo '<input type="text" value=\''.$v.'\'" name="'.$k.'" id="'.$k.'" style="display:none;"/>';
}
// echo "<a href='".$url."'> 请点击完成支付!</a><br/>" ;
echo '<input type="submit" value="请点击完成支付!" onclick="document.pay_form.submit();//window.close();" />';
echo ' </form> ';
echo '</body></html>';
return;
}

//测试使用header跳转,发现连连会提示
//出错了!
//商户域名未报备,请联系客服处理[1006][商户唯一单号:xxxxxxxxxxxxxxxx]
// header('Location: '.$url ,TRUE,301);

//跳转至支付平台
echo '<script type="text/javascript">var url=\''.$url.'\';window.location.href=url; </script>';

测试发现并未跳转
但是点击提交按钮也不行
使用a链接也不行
都还是提示 未报备

添加form 的target="_blank" 属性
测试 手动点击是可以成功跳转
但是js 开的窗口会被拦截
要么就是压根就没有反应

折腾几小时了
心想不行
实在不行就让再新开个页面处理了

于是想着能让js 自动点击a标签或者是submit按钮

<?

// if(strpos($_SERVER['HTTP_USER_AGENT'],"MSIE")) {
echo '<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body onload="javascript:document.pay_form.submit();" >';
echo ' <formid="pay_form" name="pay_form" method="get" target="_blank" action="'.$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'" >';
foreach ($urlarr as $k => $v)
{
echo '<input type="text" value=\''.$v.'\'" name="'.$k.'" id="'.$k.'" style="display:none;"/>';
}
echo "<a href='".$url."'> 请点击完成支付!</a><br/>" ;
echo "<script>var url='".$url."'; //var newTab1=window.open('about:blank'); newTab1.location.href=url; </script>";
echo "<script> window.onload=function(){ window.close(); } </script>";
echo '<input type="submit" value="请点击完成支付!" onclick="document.pay_form.submit();//window.close();" />';
echo ' </form> ';
echo '</body></html>';
return;
// }

但是测试下来
js新开的窗口直接被拦截了

还是不行

突然灵光一现
想这能不能在 window.onload 的时候
直接跳支付连接
于是代码改为
<?
//获取url 链接
//***********
$url="https://llpay.com?xxxxx=xxx&xxx=xx";
$url=base64_decode( $url );
$checkurl=parse_url($url);
if (!$checkurl['scheme'] || !$checkurl['host']) {
// p( parse_url($url));
die('err URL');
}
$query=$checkurl['query'];
$urlarr=array();
parse_str($checkurl['query'],$urlarr);
$url2= http_build_query($urlarr);
$url3=$checkurl['scheme'].'://'.$checkurl['host'].$checkurl['path'].'?'.$url2;

if(strpos($_SERVER['HTTP_USER_AGENT'],"MSIE")) {
echo '<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title></head><body>';

echo "<script>var url='".$url."'; //var newTab1=window.open('about:blank'); newTab1.location.href=url; </script>";
echo "<script> window.onload=function(){ window.location.href=url; } </script>";

echo '</body></html>';
return;
}

echo '<script type="text/javascript">var url=\''.$url.'\';window.location.href=url; </script>';
// redirect( $url );
// header('Location: '.$url ,TRUE,301);
die;

测试发现神奇的可以使用了!
猜测应该是IE对html 的 语法要求严格一些

新增一个测出来的问题,

360浏览器,如果商户地址使用的是IE,

但连连是急速内核的话,

也会提示商户未报备

 

以下是连连支付提供的问题说明和解决方案


在IE中用javascript做跳转,比如用window.location.href = “http://www.abczn.com”; abczn无法取到浏览器请求的HTTP referrer,因为IE清空了document.referrer

而其他主流浏览器Firefox和Chrome都会保留referrer,这意味着IE又要享受“部长级”特殊待遇了:

if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
    var referLink = document.createElement_x('a');
    referLink.href = url;
    document.body.appendChild(referLink);
    referLink.click();
else {
    location.href = url;
}这样的原理就是给IE浏览器的页面偷偷加了个链接,然后自动点这个链接,于是referrer就能保留了

 

 


后记:

header 跳转的各类问题

IE浏览器如果输出的内容字节太小(小于512字节),那么就会被忽略

 

h tt p://blog.csdn.net/default7/article/details/12995359

 


兼容IE的javascript跳转(可传递referer)

window.location方式跳转页面,会造成IE下跳转到的页面无法获取到跳转来源(referer)。stackoverflow中评论里贴出了一段代码是在页面的body中增加了一个a标签,然后通过javascript点击此a标签来解决ie的此问题,但俺觉着通过UserAgent来判断IE不是很靠谱(众所周知的国内各种加壳版本浏览器),正好记着以前看到过一个IE的特性就是.click是IE特有的一个属性。修改了下。stackoverflow的脚本就有了现在俺在用的这个版本:

function goTo(url) {

var a = document.createElement("a");

if(!a.click) { //only IE has this (at the moment);

window.location = url;

return;

}

a.setAttribute("href", url);

a.style.display = "none";

document.body.appendChild(a);

a.click();

}

BTW:此脚本必须放在body标签后,否则会报一个document.body无法找到的错

 

欢迎大家加入我们的QQ群:307469859

原文链接:一段js引发的血案 --IE js 新窗口跳转 问题,转载请注明来源!

0