开发过程中疑难杂症解决方案总结一

一、批次加载列表数据
问题场景:机票列表页面一直处于loading状态,服务器日志显示已经返回了数据,但是ajax请求一直处于挂起状态,导致页面也一直loading中。
分析原因:通过排查,发现服务器返回的数据量过大(大约2M)导致ajax假死,网上有人说ajax请求的响应时间为10秒,超过了就会假死。
解决方案:
1、把原先的ajax请求分成多批次,每次请求让服务器返回5条数据,这样就避免了一次性响应数据量过大的问题;
2、服务端把数据做缓存,分批次从缓存读取数据给客户端;
3、客户端ajax每次请求返回后根据服务端返回的完成标识判断是否再次发送请求;
相关代码:
客户端:

 
服务端:

 
问题总结:
1、ajax请求响应时间为10秒,超过后请求就挂起,浏览器进入假死状态;
2、jQuery ajax实现分批次请求数据;
3、从Cache中利用linq分批次读取数据;

注:
用ajax设置请求头部超时时间,如:
ajax.setRequestHeader("connectionTimeout","5000");


二、APP自动登录实现和登录跳转问题
需求场景:公司要做一个APP,套个壳,把现有的几个H5站点加进去。这样APP和H5端用户的登录信息需共享,并且当H5站点重启时不再跳转原H5的登录页面,而是跳转到APP的登录界面。
解决方案:
1、APP端通过把用户登录信息写入H5的cookie中来传递,当用户退出APP再次登录时cookie会更新。
2、H5端站点通过HttpModule拦截HTTP请求,如果H5站点登录失效(比如MemCache或Session过期)就调用自动登录API来更新H5端的登录状态;
3、如果H5站点重启(比如重新发布站点或修改web.config),则跳转到APP登录界面;
相关代码:

HttpModule实现:

 H5站点引入:
<system.webServer>
    <modules>
      <add name="AutoLoginModuleNew" type="XFK.AppLYTravel.Common.AutoLoginModule,XFK.AppLYTravel.Common" />
    </modules>
</system.webServer>

H5跳转方法

H5端在BasePage中调用,如:

 
遇到的问题:
1、H5如何判断请求来自APP;
2、HttpModule获取请求资源mime类型的时机;
3、Http请求管道事件(如BeginRequest、EndRequest)对于js脚本执行的影响;
例如IOS端跳转APP登录页的方法是这样的:

<script>
    function loadURL(url) {
        var iFrame;
        iFrame = document.createElement("iframe");
        iFrame.setAttribute("src", url);
        iFrame.setAttribute("style", "display:none;");
        iFrame.setAttribute("height", "0px");
        iFrame.setAttribute("width", "0px");
        iFrame.setAttribute("frameborder", "0");
        document.body.appendChild(iFrame);
        iFrame.parentNode.removeChild(iFrame);
        iFrame = null;
    }
    loadURL("haleyAction://tokenTimeOut");
</script>

这段js代码在EndRequest事件中可以输出到</html>标签外,页面最底部,如下图:

这时候所有的DOM元素都已加载完毕,所以执行没问题;
但是放在BeginRequest里,js代码被输出到了页面最顶部,如:

这时候因为DOM元素还未加载好,会有如下错误:


解决方案:
1、APP端通过修改http请求头User-Agent来标识;
2、精确获取mime类型要在EndRequest事件里,如:string mimeStr = _context.Response.ContentType;
在BeginRequest里不管请求资源是页面、脚本、图片或是其他,获取的都是"text/html"

3、这种情况,用window.onload包装一下就可以正常执行了,如:

<script>
    window.onload=function(){
        function loadURL(url) {
            var iFrame;
            iFrame = document.createElement("iframe");
            iFrame.setAttribute("src", url);
            iFrame.setAttribute("style", "display:none;");
            iFrame.setAttribute("height", "0px");
            iFrame.setAttribute("width", "0px");
            iFrame.setAttribute("frameborder", "0");
            document.body.appendChild(iFrame);
            iFrame.parentNode.removeChild(iFrame);
            iFrame = null;
        }
        loadURL("haleyAction://tokenTimeOut");
    }
</script>

 
总结:
1、HttpModule的BeginRequest、EndRequest事件对于页面元素(HTML和js)加载顺序的影响;
2、获取mime类型一定要在EndRequest事件里,并且用Response.ContentType方法;
3、session依赖于cookie,当cookie在页面中失效后session也会失效;

三、用到的或了解到的跨域知识总结
1、WEB站点调用远程API,通过Ajax请求本地Handler或Controller,而本地Handler或Controller利用HttpWebRequest和HttpWebResponse与远程API交互;
2、WEB站点在调用远程登录接口时,HTTP请求中带上cookie,实现统一登录;
3、实现跨域的技术如JSONP、CORS、postMessage等作为技术储备;

posted @   skybirdzw  阅读(817)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示