JS中跨域和沙箱的解析

先来直接分析源码,如下:

<!DOCTYPE HTML><html>
<
head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0"/> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta name="format-detection" content="telephone=no" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="Content-Language" content="zh-cn" /> <meta name="MobileOptimized" content="100%"> <title>jQueryMobile滑动事件测试页面</title> <style type="text/css"> .under_bot{ width:100%; position:fixed; bottom:0; left:0;} .underToolsBar{ padding:7px 0 3px 0; background:#efefef; border-top:1px solid #e3e3e3; width:100%; overflow:hidden; z-index:99;} .underonlaod{ background-color:#53555D; overflow:hidden; width:100%; padding-top:10px; padding-bottom:5px; position:relative; z-index:99;} .underonlaod_left{ float:left; width:50%;} .underonlaod_right{ float:right; width:50%;} .under_bot{ position:fixed; bottom:0;} .underonlaod .close{ position:absolute; right:0; top:0; width:8%; cursor:pointer;} .tabs{ padding-bottom:40px;} </style> <link rel="stylesheet" media="screen and (max- 320px)" href="css/common.css" /> <link rel="stylesheet" media="screen and (min- 320px)" href="css/common.css" /> <link rel="stylesheet" href="css/index.css"> <script type="text/javascript" src="js/jquery-2.1.3.js"></script> <script type="text/javascript" src="js/common.js"></script> <script type="text/javascript" src="js/jquery.mobile-1.4.5.min.js"></script> <script type="application/javascript" src="js/drawPercent.js"></script> <div id='wx_pic' style='margin:0 auto; display:none;'> <img src='images/pic300.jpg' /> </div> </head> <script type="text/javascript"> $(document).ready(function(e) { //关闭 $('.close').click(function(){ $('.underonlaod').css('display', 'none'); }) var PRODUCTID = null; var PRODUCTNAME =null $.ajax({ type : "POST", contentType : 'application/json', url : getBaseUrl(), timeout:60000, data : setRequestData( "M026","", new Array( ['type','status','pageNo','pageSize'], [ 3,0,1,1] ) ), success : function(data) { if(0000==data["responseCode"]){ //alert(JSON.stringify(data.data[0].period)); $("#productName").text(data.data[0].productName); $("#expectProfitRate").text(data.data[0].expectProfitRate); $("#period").text(data.data[0].period); $("#periodType").text(data.data[0].periodType==0?"":(data.data[0].periodType==1?"个月":"")); $("#mortgage2").text(data.data[0].mortgage==null?'':data.data[0].mortgage); $('#shiwudiya').css('display', data.data[0].mortgage==null?'':'none'); $("#activeProductNo").text(data.data[0].activeProductNo); var progress = data.data[0].progress; draw_small("tagCanvas",progress,0.8,0.8); PRODUCTID = data.data[0].productId; PRODUCTNAME = data.data[0].productName; }else{ showErrorTips(data["responseMsg"],data["responseCode"]); } }, error : function(XMLHttpRequest) { showErrorTips("网络错误,请稍后再试",XMLHttpRequest); } });//first ajax stop $.ajax({ type : "POST", contentType : 'application/json', url : getBaseUrl(), timeout:60000, data : setRequestData( "M040","" ), success : function(data) { if(0000==data["responseCode"]){ for(var i=0; i<data["data"].length; i++){ $("#bannerList").append('<li><a href="'+data["data"][i]["linkUrl"]+'" target="_self"><img src="'+data["data"][i]["picUrl"]+'" alt="'+data["data"][i]["picName"]+'"></a></li>'); $("#bannerControl").append('<li></li>'); } var countPicNum = data["data"].length; $(".control").css({"width":(countPicNum*15)+"px"}); $("#bannerControl").css("margin-left",-countPicNum*15*0.5+"px"); $("#bannerControl li:first").addClass("active"); $("#bannerList li").css("width",$(window).width()+"px"); $("#bannerList").css("width",($(window).width()*countPicNum)+"px"); //alert($(".control").offset().top+"--"+$(".banner").height()); //alert($(".control").offset().left+"--"+$(".banner").width()); $("#bannerControl li").on("click",function(){ clearInterval(myInner); var num = $(this).index(); $(this).addClass("active").siblings(this).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*num)+"px, 0px) translateZ(0px)"); myInner = setInterval(function(){ var num = $("#bannerControl li.active").index(); var count = num==(countPicNum-1)?0:num+1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); },3000); }); var myInner = setInterval(function(){ var num = $("#bannerControl li.active").index(); var count = num==(countPicNum-1)?0:num+1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); //$("#bannerList").animate({"margin-left":-($(window).width()*count)+"px"}); },3000); $(".banner").on("swipeleft",function(){ clearInterval(myInner); var num = $("#bannerControl li.active").index(); var count = num==(countPicNum-1)?0:num+1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); myInner = setInterval(function(){ var num = $("#bannerControl li.active").index(); var count = num==(countPicNum-1)?0:num+1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); },3000); }); $(".banner").on("swiperight",function(){ clearInterval(myInner); var num = $("#bannerControl li.active").index(); var count = num==0?(countPicNum-1):num-1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); myInner = setInterval(function(){ var num = $("#bannerControl li.active").index(); var count = num==(countPicNum-1)?0:num+1; $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active"); $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)"); },3000); }); }else{ //showErrorTips(data["responseMsg"],data["responseCode"]); } }, error : function(XMLHttpRequest) { showErrorTips("网络错误,请稍后再试",XMLHttpRequest); } }); $("#tuijianTag").on({ click:function(){ setSessionData('productId',PRODUCTID); setSessionData('productName',PRODUCTNAME); window.location.href='./product_summary.html'; } }); $("#btn_buyTag").on("click",function(){ setSessionData('productId',PRODUCTID); setSessionData('productName',PRODUCTNAME); window.location.href='./product_summary.html'; }); $("#banner").css("height",($(this).width()/16)*7); $(".ui-loader").detach(); }); </script> <style> .special { padding: 8px 0 0 0; } </style> <body> <center> <div class="banner" id="banner">

  <ul id="bannerList" style="transition: 1000ms cubic-bezier(0.1, 0.57, 0.1, 1); -webkit-transition: 1000ms cubic-bezier(0.1, 0.57, 0.1, 1); transform: translate(0px, 0px) translateZ(0px)"> </ul> <div class="control"> </div> <ul id="bannerControl"> </ul> </div> <!--END banner--> <div class="tabs"> <div class="ht10"></div> <div class="tabContent" id="tabContent2" style="display:;"> <div class="tuijian"><img src="images/icon_tuijian.png"><span id="productName">路虎</span></div> <div class="ht3"></div> <div class="tuijianTag" id="tuijianTag"> <table> <tbody> <tr> <td><span id="expectProfitRate" class=" f28 cred fb"></span><span class="f16 fb cred">%</span></td> <td><span id="period" class="f28 fb c999"></span><span id="periodType" class="f16 fb c999"></span></td> <td> <div class="tagProgress"> <canvas id="tagCanvas" width="64" height="64">您的浏览器不支持HTML5 canvas,请换用现代浏览器。</canvas> </div> </td> </tr> <tr> <td class="c999 f14">年化收益</td> <td class="c999 f14">融资期限</td> <td class="c999 f14">融资进度</td> </tr> </tbody> </table> </div> <div class="ht3"></div> <div class="advantage" id="shiwudiya"> <img src="images/icon_diya.png" style="padding-left:10px; 18px; position:relative; top:4px;"><span id="mortgage2" style="color:#333; font-size:1.4rem; font-weight:100; padding-left:5px;"></span> </div> <div class="ht5"></div> <button type="button" id="btn_buyTag" class="com_btnBlue" style="70%; line-height:3.4rem">立即购买</button> <div class="ht10"></div> <div class="f16 fb tl" style="color:#333; background:#E4E4E4; padding:8px">理财产品</div> <div class="indexProduct" onClick="window.location.href='./anyTime.html'"> <div class="p_l"> <img src="images/icon_bigWallet.png"> </div> <div class="p_r"> <div class="ht5"></div> <h1 class="f16 fb c666">月月涨</h1> <div class="ht10"></div> <h1 class="f14 c666"><span class="f18 fb">7</span><span class="fb">%-</span><span class="f18 fb">12.5</span><span class="fb">%</span>,年化月月涨</h1> </div> <div style="background:#C12928; 80px; height:20px; border-radius:10px 0 0 10px; text-align:center; font-weight:bold; color:#fff; font-size:14px; position:absolute; line-height:20px; right:0px;">每月可取</div> <img src="images/moreDelta.png" width="13" style=" position:absolute; right:10px; top:50px;"> <!--z-index:99--> </div> <div class="ht10" style="background:#e4e4e4; 100%;"></div> <div class="indexProduct" onClick="window.location.href='./product_list.html'"> <div class="p_l"> <img src="images/icon_bigTag.png"> </div> <div class="p_r"> <div class="ht5"></div> <h1 class="f16 fb c666">全民安选</h1> <div class="ht10"></div> <h1 class="f14 c666"><span class="f12">最高</span><span class="f18 fb">15</span><span class="fb">%</span>,定期投资理财</h1> </div> <div style="background:#C12928; 24px; height:24px; border-radius:12px; text-align:center; font-weight:bold; color:#fff; font-size:18px; position:absolute; line-height:24px; top:-6px; right:5px;"><var id="activeProductNo"></var></div> <img src="images/moreDelta.png" width="13" style=" position:absolute; right:10px; top:50px;"> <!--z-index:99--> </div> <div class="ht20" style="background:#e4e4e4; 100%;"></div> </div> </div> </center> <div class="ht40"></div> <div class="ht10"></div> <div class="under_bot"> <div class="underToolsBar" style="padding:7px 0 0"> <ul> <li class="active"><a href="index.html" target="_self"><img src="images/icon_wallte.png" height="21"> <p>首页</p> </a> </li> <li><a href="./product_list.html" target="_self"><img src="images/icon_up_grey.png" height="21"> <p>投资项目</p> </a> </li> <li onClick="if(getSessionData('customerId')==null){setSessionData('indexBackHref','./myWealth_index.html');window.location.href='./login.html'}else{window.location.href='./myWealth_index.html'}"><img src="images/icon_cash_grey.png" height="21"> <p>我的财富</p> </li> <li><a href="./more.html" target="_self"><img src="images/icon_more_grey.png" height="20"> <p>更多</p> </a> </li> </ul> <div class="underonlaod" > <div onClick="window.location.href='./downApp.html'"> <div class="underonlaod_left"> <img src="images/onlaod_left.png" width="80%" /> </div> <div class="underonlaod_right"> <img src="images/onlaod_right.png" width="62%" /> </div> </div> <a href="javascript:void(0)"><img src="images/close.png" class="close" /></a> </div> </div> </div> </body> </html>

接下来,按加载顺序来分析一下,找到html5页面中滑动事件区域:

<div class="banner" id="banner">
    <ul id="bannerList" style="transition: 1000ms cubic-bezier(0.1, 0.57, 0.1, 1); -webkit-transition: 1000ms cubic-bezier(0.1, 0.57, 0.1, 1); transform: translate(0px, 0px) translateZ(0px)">  
    </ul>
    <div class="control">
    </div>
    <ul id="bannerControl">
        </ul>
</div>
  • 代码:transition: 1000ms cubic-bezier(0.1, 0.57, 0.1, 1);cubic-bezier即为贝兹曲线中的绘制方法。图上有四点,P0~3,其中P0、P3是默认的点,对应了[0,0], [1,1]。而剩下的P1、P2两点则是我们通过cubic-bezier()自定义的。cubic-bezier(x1, y1, x2, y2) 为自定义,x1,x2,y1,y2的值范围在[0, 1],指定元素状态的变化速率函数,其取值基于贝赛尔曲线函数。规定了过渡效果的速度曲线。
  • 代码:transform: translate(0px, 0px) translateZ(0px)。是CSS3中的属性,实现动画效果。transform: translate(a, b);表示元素x方向位移a,y方向位移b。transform: translateX(a);则表示元素x方向位移a,y方向不变。
    $.ajax({
                type : "POST",  
                contentType : 'application/json',  
                url : getBaseUrl(),
                timeout:60000,  
                data : setRequestData(
                    "M040",""
                ), 
                success : function(data) {
                    if(0000==data["responseCode"]){
                        for(var i=0; i<data["data"].length; i++){
                            $("#bannerList").append('<li><a href="'+data["data"][i]["linkUrl"]+'" target="_self"><img src="'+data["data"][i]["picUrl"]+'" alt="'+data["data"][i]["picName"]+'"></a></li>');
                            $("#bannerControl").append('<li></li>');
                        }
                        var countPicNum = data["data"].length;
                        $(".control").css({"width":(countPicNum*15)+"px"});
                        $("#bannerControl").css("margin-left",-countPicNum*15*0.5+"px");
                        $("#bannerControl li:first").addClass("active");
                        $("#bannerList li").css("width",$(window).width()+"px");
                        $("#bannerList").css("width",($(window).width()*countPicNum)+"px");
                        //alert($(".control").offset().top+"--"+$(".banner").height());
                        //alert($(".control").offset().left+"--"+$(".banner").width());
                        $("#bannerControl li").on("click",function(){
                            clearInterval(myInner);
                            var num = $(this).index();
                            $(this).addClass("active").siblings(this).removeClass("active");
                            $("#bannerList").css("transform","translate("+-($(window).width()*num)+"px, 0px) translateZ(0px)");
                            myInner = setInterval(function(){
                                var num = $("#bannerControl li.active").index();
                                var count = num==(countPicNum-1)?0:num+1;
                                $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                                $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            },3000);
                        });
                        var myInner = setInterval(function(){
                            var num = $("#bannerControl li.active").index();
                            var count = num==(countPicNum-1)?0:num+1;
                            $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                            $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            //$("#bannerList").animate({"margin-left":-($(window).width()*count)+"px"});
                        },3000);
                        
                        $(".banner").on("swipeleft",function(){
                            clearInterval(myInner);
                            var num = $("#bannerControl li.active").index();
                            var count = num==(countPicNum-1)?0:num+1;
                            $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                            $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            myInner = setInterval(function(){
                                var num = $("#bannerControl li.active").index();
                                var count = num==(countPicNum-1)?0:num+1;
                                $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                                $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            },3000);
                        });
                        
                        $(".banner").on("swiperight",function(){
                            clearInterval(myInner);
                            var num = $("#bannerControl li.active").index();
                            var count = num==0?(countPicNum-1):num-1;
                            $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                            $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            myInner = setInterval(function(){
                                var num = $("#bannerControl li.active").index();
                                var count = num==(countPicNum-1)?0:num+1;
                                $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                                $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                            },3000);
                        });
                        
                    }else{
                        //showErrorTips(data["responseMsg"],data["responseCode"]);
                    }            
                },  
                error : function(XMLHttpRequest) {  
                    showErrorTips("网络错误,请稍后再试",XMLHttpRequest);
                }  
            });

参考:http://blog.csdn.net/sadfishsc/article/details/7165163/

对于bannerList的操作全集中在jQuery的ajax请求当中,分析如下:

在发送ajax请求的时候,调用common.js中的setRequestDate函数,将“M040”,“”发送过去。

函数setRequestDate的实现如下:函数中拼接了请求数据时候的公共报文数据。

/*
ajaxPost请求data
version    版本
appVersion    客户端应用版本
requestTime    请求时间
bizType    业务类型
customerId    客户ID
deviceId    设备号
token    登录token
jsonArray    页面请求数据数组,[param],[value]
*/

function setRequestData(bizType,customerId,jsonArray){
    //version、appVersion、requestTime默认固定
    var version = "1.0";
    var appVersion = "HTML5";
    var requestTime = getNowTime();
    var deviceId = "";
    var token = "";
    var allData = null;
    var baseData = '{"version":"' + version 
                  + '","appVersion":"'+ appVersion
                  + '","requestTime":"' + requestTime
                 + '","bizType":"' + bizType
                 + '","customerId":"' + customerId
                 + '","deviceId":"' + deviceId
                 + '","token":"' + token;
    if(arguments.length==2){
        allData = baseData + '"}';
    }else{
        var inputDataStr = "";
        for(var i = 0; i < jsonArray[0].length; i++){
            if(i==jsonArray[0].length-1){
                inputDataStr = inputDataStr+'"'+jsonArray[0][i]+'":"'+jsonArray[1][i]+'"';
            }else{
                inputDataStr = inputDataStr+'"'+jsonArray[0][i]+'":"'+jsonArray[1][i]+'",';
            }
        }
        allData = baseData+'","data":{'+inputDataStr+'}}' ;
    }
    return allData;
}

当返回正常状态时,这部分在数据库中定义如下:

HTML DOM setInterval() 方法,其中 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

setInterval(code,millisec)
参数    描述
code    必需。要调用的函数或要执行的代码串。
millisec    必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。
var myInner = setInterval(function(){
                        var num = $("#bannerControl li.active").index();
                        var count = num==(countPicNum-1)?0:num+1;
                        $("#bannerControl li:eq("+count+")").addClass("active").siblings($("#bannerControl li:eq("+count+")")).removeClass("active");
                        $("#bannerList").css("transform","translate("+-($(window).width()*count)+"px, 0px) translateZ(0px)");
                        //$("#bannerList").animate({"margin-left":-($(window).width()*count)+"px"});
                    },3000);
clearInterval(myInner);

 然后我们看到要实现图片的滑动效果,需要使用两个函数swipeleft和swiperight。他们是由jquery.mobile-1.4.5.min.js来提供的。光加载它就需要195KB,这样对于2G 或 3G网络下来加载HTML5网页,会带来很不好的用户体验。

基于移动设备端带宽的限制,如果我们加载的页面量太大,就会导致很差的用户性体验,所以,采用了swipe.js来代替jquery.mobile的插件,来实现左右滑动的效果。具体实践如下:(参考方案:http://www.jiawin.com/swipe-mobile-touch-slider)可见实现上述滑动事件的原因是使用了jquery.mobile.min.js中的swipeleft函数和swiperight函数。(我们在W3C在线测试我们的解决方案:http://www.w3cschool.cc/jquerymobile/event-swipeleft.html

先来普及几个知识点:

  • 跨域访问:从www.qucaifu.com发送一个ajax请求到www.baidu.com,你会发现是没有数据内容的。原因就在于跨域访问。其实,跨域访问是可以发送成功的,只是无法接受到传回来的数据而已。为什么呢?这就是JavaScript中的沙箱模式。详情可以参考JavaScript sandbox和浏览器安全策略。解决方法是在Chrome的快捷方式中,加入“ --disable-web-security”。注意前方有一个空格,要加在快捷方式->菜单目录下的。

  详情参考:http://jingyan.baidu.com/article/7c6fb4281d685780642c900a.html

  • 关于HTML5页面的调试,将Chrome浏览器缩小,然后F12调试,会有各种适配手机的方案。非常方便。(注意生产环境和测试环境的切换,要通过前台common.js中的getURL来根据返回的地址来决定)。

*************************************************************************************************************************

关于WEB页面的优化问题:

进行优化前,关键是剖析当前的web性能,找到性能瓶颈,从而确定最需改进的地方;如果精力有限,首先将精力放在能明显提升性能的改进点上;<<高性能网站建设指南》提出了一个性能黄金法则:只有10%-20%的最终用户响应时间花在了下载HTML文档上;其余的80%-90%的时间花在了下载页面中的所有组件上。所以,我们还是从后台开始:

案例说明,优化之前的网站规模:2个js、一个页头、一个页脚;3个css;类型:博客类站点;后台逻辑简单;首页不到10个sql查询;首页html文档52kb;

第一步,后台优化,启动页面缓存:实验站点首页后台逻辑并不复杂,不超过10个Sql查询,通过查看时间线,本站在获取HTML文档时,花费的时间不到总响应时间的20%,优化之前没有使用缓存,所有的数据都是从数据库读取,这里,我们使用静态页面缓存,将首页整个页面完全的存放在缓存中(关于YII静态页面缓存的使用,参考这里);通过查看html文档的生成时间来检测优化效果;首字节时间为376ms;html生成的时间大大缩短,后台时间减少了一倍。(http://www.****123.com/html/exception/385/385997_385993_385996.htm)

 

 

http://www.w3cplus.com/source/jquery-plugins-that-handle-touch-events-43-items.html

h5本地测试小Tip:在chrome浏览器访问位置后加入 --rgs --disable-web-security 可以允许浏览器进行跨域访问 

"C:Program Files (x86)GoogleChromeApplicationchrome.exe" --rgs --disable-web-security

http://www.111cn.net/wy/jquery/78937.htm

http://www.111cn.net/wy/jquery/78937.htm

https://github.com/stephband/jquery.event.swipe/blob/master/README.md

http://www.cnblogs.com/aimyfly/p/3843977.html

http://www.8abd.com/?p=586

http://www.cnblogs.com/aimyfly/p/3843977.html

http://www.zhangxinxu.com/wordpress/2011/11/html5-javascript%E7%A7%BB%E5%8A%A8web%E5%BC%80%E5%8F%91%EF%BC%88%E4%B8%80%EF%BC%89/

 http://www.codeforge.cn/read/215221/jquery.touchwipe.1.1.1.js__html

http://blog.csdn.net/szwangdf/article/details/43153077

http://www.cnblogs.com/aimyfly/p/3843977.html

原文地址:https://www.cnblogs.com/RunForLove/p/4587643.html