首页> web技术

web技术 存档

解决IE缓存ajax GET信息的问题

2013年09月05日 分类目录 :web技术 0

今天测试组在测试我们发布的网站的时候发现登录的用户看到的信息与期望结果有所不同,而且该现象只在IE下出现,Chrome中显示的数据与期望值相符。于是在持续抱怨奇葩的IE的同时不得不去调查原因,终于在不懈地挖掘下,发现了造成这种情况的奇葩原因。

bug原因

被发现问题的这个功能我们设计的是通过ajax使用GET调用controller中的action来获取数据list,然后显示在界面上。当我debug跟踪相关action的时候发现,被调用的action只在浏览器第一次跑我们的网站的时候才会被调用,之后无论是更换登录的id还是F5刷新页面,这个action都没被调用。于是就将重心放在了浏览器缓存上,事实证明也的确如此。
当分别使用IE和Chrome的开发者工具来查看相关网络情况的时候,我们发现两者在request header中有一个关键的不同。chrome在发出的情况中默认包含了Cache-Control:no-cache信息,而IE没有。这也就造成了IE在执行ajax的时候会从缓存中提取曾经被缓存下来的结果,而chrome则向服务器发出请求重新获取数据。

解决方案

针对上述发现的原因,我尝试了2种不同的方案来强制IE向服务器发出请求重新获取数据,这里做一个分享。
1.使用post替换get。
2.依然使用get,但添加cache:false的header info。
当使用上述任意一种方案之后,在request header中均看到来Cache-Control:no-cache信息。

最后,不得不在抱怨一句,微软的IE还真是奇葩,这已经不知道是最近第几次发生只在IE中出现问题的情况了。尤其是IE还会有IE9错误,IE10正确的奇葩现象(由于我们的项目只要求IE9以上,所以IE9以下版本直接无视,否则可能更加悲剧了吧)

,

利用jQuery UI定制表单提交确认对话框

2013年07月08日 分类目录 :web技术 0

在Web开发过程中,确认对话框(confirm dialog)是一个非常常用的组件,无论是删除内容还是创建内容,我们经常会看到这样一个提示框来请求确认执行。如果不追求界面的美观、又希望使用简单,那么就用javascript提供的confirm()方法来制作,反之则可以使用包括jQueryUI等封装了增强版Dialog的框架。

javascript的confirm():

    var confirm=confirm("确定要访问网憩阁吗?");
    if(confirm){
         window.location.href="http://wangqige.com";
    }

上面这是最简单的一个确认对话框,首先我们在调用confirm()时传入一句需要提问的问题,当用户点击“确认”按钮时跳转到指定的页面。
只是可惜confirm提供给我们的定制化性能太弱了,连Ok、cancel两个button上显示的文字都不能随意修改(只能系统本地化为当前区域惯用文字,如简体中文是“确认”和“取消”),在我这次的功能制造过程中,日方要求将“Ok”、“キャンセル”(cancel)改为日语习惯的“はい”、“いいえ”,于是我花了不少时间来调查这个问题,最终发现只有当浏览器为IE时可以借助vbscript来实现这个功能,其余浏览器则不行。于是我转而向jQuery UI方向来调查,终于完美解决了这个烦恼的问题(说完美其实也还差一点,不过这是css方面的问题)。

jQuery UI Dialog:

这是jQuery UI提供的标准化控件之一,通过对它的配置使用,我们可以很好的针对自己的需求来进行定制,而且使用也非常简单,至少我没花多少时间就实现了所有围绕它而做的操作,回头想想之前调查Upload时对Yahoo YUI的尝试,花了几天时间楞是没啥成果。废话不多说了,来段代码实际验证一番。
首先在html代码的底部添加一个空的div层,name命名为”dialog-confirm”,为了看起来舒服,而且规范化,再给加个title,代码效果如下:更新:貌似代码高亮功能出问题了,Html代码还是会被识别出来,只能不贴这部分了

这个div层是用来显示对话框的,在应用的过程中为了增加重用性,所以显示的文本内容由javascript来负责追加,而非写死在html代码中,下面来看javascript部分的代码:

  $(function() {
$( "#dialog-confirm" ).html("确定要访问网憩阁吗?");
$( "#dialog-confirm" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"确定": function() {
$( this ).dialog( "close" );
window.location.href="http://wangqige.com";
},
“取消”: function() {
$( this ).dialog( "close" );
}
}
});
});

对于Dialog所提供的方法,在此我不多作说明,如有需要可以参考官方文档,这里我只说明buttons部分。从上面的代码可知,双引号部分的文本就是Dialog上buton显示的内容,而后面则是触发click事件后的操作,在上面的例子中仅仅是关闭当前对话框,在实际开发中可以在关闭对话框之后调用自己写的function。

使用jQuery UI Dialog制造表单提交确认对话框

在本次的项目中,我所需要实现的是点击表单的submit事件之后,弹出一个对话框让用户确认提交表单。当我按照给出的示例做好对话框之后发现,jQuery UI Dialog不会终端表单的submit进程,因此当对话框仍显示在界面上,并且没有点击任何按钮的情况下,表单的submit操作已经执行完毕。理论性的内容我不是很了解,这里就不对原因进行阐述,下面直接给出解决方案。
首先创建一个简单的表单,在本示例中表单不执行任何实际操作,只是一个空表单,更新:貌似代码高亮功能出问题了,Html代码还是会被识别出来,只能不贴这部分了。之后是对提交按钮增加jQuery UI Dialog功能:

     $("#btnSUbmit").click(function(event){
            event.preventdefault();  //这句话最关键,它是jQuery提供的一个事件,用来阻止元素的默认执行动作,比如这里的表单提交
  $(function() {
$( "#dialog-confirm" ).html("确定要提交表单到网憩阁吗?");
$( "#dialog-confirm" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"确定": function() {
$( this ).dialog( "close" );
$("#myForm).submit();
},
“取消”: function() {
$( this ).dialog( "close" );
}
}
});
     })

, ,

数据库时间字段的几个技巧

2013年06月27日 分类目录 :web技术 0

用于作业环境中的数据库,通常都会在表中定义诸如“创建时间”、“修改时间”之类的字段来记录对该条记录的操作情况(对于像历史版本之类的高级应用来说,会根据“修改时间”来创建多条数据以便于恢复等操作)。在初级阶段,我们会通过在代码层手动修改这类字段,然后这是一种很不节约的办法。因此,在对数据库有了一定的了解之后,这些字段的操作就直接放在了数据库里,让数据库来自动进行修改,而不必由我们在代码层手动修改。

第一阶段的时间字段操作(代码侧)

正如前面提到的,在初级阶段,我们通常是在代码层手动修改这些时间字段,即在代码中执行sql语句,正如下面的语句这样

insert into test(created_date,modified_date) values(getdate(),getdate());
update table set modified_date=getdate() where id=?

理论上来说,这种写法一点问题都没有,也没有多少性能上的消耗,但是当应用日趋复杂,数据库愈发复杂,难免会出现些小问题。因此,对于这类字段,最佳方法当属完全在数据库段进行操作,而且是在创建数据库、表的时候就写好相关的存储过程或者触发器之类的。

第二阶段的时间字段操作(数据库侧)

在本次项目中,我使用了建表语句和触发器相结合的方式来解决这一系列的问题(由于项目关系,以下代码都只适用于sql server,其它数据库需要进行相应的修改才能实现)。首先,来看建表语句,created_date这个字段显然是用来记录这条记录的创建时间,而它只会在insert的时候赋值一次,以后不会再做修改,而modified_date虽然日后仍会修改,但是在insert的时候也需要将当前时间赋给它。既然如此,只需要参照如下修改建表语句就可以了。

create table test(
id int indentify(1,1) not null primary key,
created_date datetime not null default getdate(),
modified_date datetime not null default getdate()
)

说完建表语句,接下来看看每次修改数据时对modified_date进行修改的数据库端实现方式(同样只适用于sql server,其他数据库请进行相应的修改)。

create trigger trigger_test
on test
for update
declare @id int
begin
  select @id=id from inserted
  update test set modified_date =getdate()
  where id=@id
end

, ,

HTML file控件上传文件失败调查结论

2013年06月19日 分类目录 :web技术 0

前言

最近结束了android项目的开发,转做asp.NET网站的开发工作,由于之前从未接触过.NET项目,所以许多功能的实现都要做调查。我除了调查jQuery的使用之外,主要还负责了文件上传下载模块的功能实现。

bug经过

在调查上传功能的过程中,遇到了一个不能算是技术问题的小问题,耽搁了我不少时间,为了避免日后再犯类似问题,特此记录。
当我完成编码并运行测试的时候,发现选择的文件都没有上传到指定的文件夹下(此时我可以保证服务器端的Controller保存模块代码编码没有问题,可以实现保存操作),于是使用Debug监测相关代码,结果发现Requet中Files为空,并没有存入file控件选择的文件。在确定问题之后就此进行深入调查,最后发现,原因是我没有给控件添加name属性,所以导致无法传递。

详细原因:

在HTML中,file控件value值是以键值对的形式来保存并传递的,即给控件定义的name为key,选择的文件路径为value。因此没有定义name的file控件会被忽略掉。而我忽略了这种特性,只给控件定义了一个class来方便部分JavaScript的操作。

针对此次bug的引发观点:

HTML控件可选属性中有id,name,class三个,而它们存在的意义基本一致,既然如此为什么要区分出三个来呢?我看到不少地方的代码,给这三者赋了相同的值,某种程度上来说不是多此一举吗?在这个案例中,我就是因为只定义了一个class来使用而造成了后续的问题?
现在的IDE在静态代码监测并警示上已经做得很好了,解决了不少可能出现的问题,但是我没有给file控件赋name这个小问题竟然没有警示(至少我使用的visual studio2012是这样的),以至于花费了我不少时间来调查。

,

JTDS的no suitable driver found问题

2013年04月08日 分类目录 :android技术| web技术 0

      去年9月,由于项目需要,调查了一番android平台上通过JTDS直连服务器端的SQL server的技术实现,当时写了篇日志《android通过JTDS直连SQL Server》,之后由于优先度的缘故,相关功能模块的实现一直留到现在。

      这几天在学习相关功能模块的式样书的同时,做了个DEMO原型(上述日志中的DEMO的基础上)来测试一些技术点,在这过程中遇到了些小问题,这里记录一下。

      在我上次调查JTDS的时候,我使用的是jtds-1.2.6版本,因为当时没有把jar包留下备份,所以这次只能重新下载。于是照惯例去jtds项目网站下载jar包,然后看到现在最新版本是1.3,所以就没想太多直接用它了,悲剧也就此产生。当我将它放入原型项目中并运行应用时,Connection无限报NullPointerException,于是开始走Debug调查出问题的地方,最终发现在注册驱动时就已抛出异常(ClassNotFoundException),具体内容为“no suitable driver found”。

try {
 Class.forName(DBDefine.JTDS_NAME);// load the jtds driver
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }

       当找到问题之后,我祭出Google大招,开始寻找解决办法,可惜国内外的技术博客、论坛等都没能解决我的问题(虽然相关问题有很多,但是网友给出的解决办法或指出的问题均不适用于我的实际情况)。正当我一筹莫展之时,无意间在jtds项目网站的Discussion中看到一个帖子,这才知道原来jtds1.3是基于jdk7.0的,并不支持jdk6.0,因此改用稍低一点的版本之后就OK了。

      总结,对于终端用户来说,软件越新可能性能等各方面都越好,但是对于开发者来说,更新不一定越好,新版本的依赖情况可能会更严重,还是选择合适的版本更好。

,

将域名从name.com迁移到Godaddy

2010年07月26日 分类目录 :web技术 1

      去年购买的这个域名(http://wangqige.com/)马上就要到期了,趁续费的机会顺便就把域名从name.com迁移Godaddy来了,不为别的,为的就是Godaddy支持支付宝付账,省去了我在淘宝上找人往我的Paypal里充值这一步骤。

     首先打开Godaddy,登录帐户,如果没有帐户则注册一个,然后选择“Products”->“Domains”->“Transfer Domain”(如图所示)开始迁移工作。

输入需要迁移的域名

如果需要继续添加迁移域名则继续输入域名,否则点击“Checkout”

点击“Checkout”后会弹出一个推介广告,无视就可以了。点击“No!Thanks”

然后开始对域名进行设置,一般全部按照默认的就可以了,如果需要增值服务的话可以根据实际需求进行设置。

一切就绪后进入购物车,进行支付工作,选择Godaddy的原因就是支持支付宝,因此我就用支付宝来支付了。这里需要说明一下,支付宝支付到账会有个时间差,因此支付成功后,购物车里还是显示需要你支付,别去管它,过了大概10分钟后,邮箱中收到确认信就说明支付成功了。

接下来继续迁移域名工作:

从左侧菜单栏中进入“Domain Manager”

在Domains的下拉菜单中选择“Pending Transfers”,进入迁移工作的第二步。

点击右侧“Authorization”->“Begin Transfer Authorization”

在弹出的对话框中输入收到的邮件中的ID和CODE,进入下一步,输入原注册商那的“Auth Code”

当完成迁移工作的第二步之后,会卡在第三步,耐心等待5天之后就可以完成迁移工作了(长夜漫漫啊!)

获取属于自己的免费SSL认证

2010年07月09日 分类目录 :web技术 2

SSL(Secure Sockets Layer)认证可以帮助我们加密通过互联网传输的数据,如果我们正运行着一个博客或个人主页,并从一个不安全的公共热点网络(如咖啡厅、机场等)访问它们时,它将会起到作用。

我们通过不安全的链接访问网站的登录信息可以被拦截并破解,SSL证书会在传输登录数据到ISP/服务器前对其进行加密,以使其难以被窃听者侵入,这就是银行、金融机构、商业站点等使用SSL来保护登录信息、用户身份信息和信用卡数据的原因。

如果从 Verisign, GoDaddy等服务提供商购买SSL证书,那我们将花费一笔数额较大的费用,对于那些并未运行关键任务的门户网站,这并不值得。因此,让我们考虑一下从StartSSL获得一个免费的SSL认证吧。

获得免费的SSL证书

我们只需要填一个简单的注册表单就可以获得免费的SSL证书了,所有需要填的细节包括:家庭/公司地址,电话号码是必须要填的。一旦注册完成,一封带有认证码的邮件将被发送到我们指定的邮箱里。

输入验证码之后,申请的验证将进入第二个阶段,我们建议和StartSSL团队联系前请先等待大概6小时。事实上,我在不到5分钟的时候就收到了确认邮件,其中含有一个帐号链接。记住,这封邮件(这个链接)只有24小时的有效期限,因此请尽快处理。

安装SSL证书

StartSSL提供了没有限制和隐性成本的免费证书,我们可以选择128位或256位的加密码。

我们可以在高安全等级和中等安全等级中选择一个合适的密钥类型。一旦选中密钥类型,它将被立刻生成并且我们将被带入安装页面。

一但“Install”按钮被点击,刚刚生成的密钥证书将会被安装好。之后会出现一个下载并保存证书到硬盘上的按钮提供给我们,我强烈建议每一个使用者都照做这一步。

现在,我们的证书已经被安装在浏览器中了,接下来我们可以点击“Authenticate”进入控制面板(不需要用户名和密码),我们的身份是通过唯一的密钥来确认的,并且它是非常非常重要的,请确保其安全性!

验证域名
授权完成后,我们可以开始在验证向导的指引下验证需要用到SSL加密技术的域名和电邮地址。在下拉菜单中,我们可以选择合适的选项来让我们继续验证域名,一但我们输入域名,一封邮件将被发送到我们的邮箱中来确认域名拥有者。

当电邮地址被确认后,域名也将被验证完毕。事实上,由于这是免费的SSL证书,因此StartSSL要求用户每30天重新验证一次,验证步骤和第一次的相同。

证书向导
当我安装好我的WordPress博客后,我就选择这个服务商的证书服务。我们需要输入一个密码来创建密钥,然后我们需要输入使用证书技术的域名,请注意,域名是必填项!

创建后的证书将支持所有域名(包括子域名)。

最后一步,我们将看到一个显示了证书信息的文本框,复制这段内容并粘贴到文本编辑器中,另存为ssl.crt。

同一个页面上也有一个链接,该链接让我们下载中级和根证书,将他们下载到同一个文件夹里。

上传文件到服务器

在FAQ的“如何安装部分”,选择我们的服务器安装信息,例如Apache服务器的话,我们将会得到一串代码,将其粘贴到服务器中间的根文件夹的http.conf或ssl.conf文件中。在同一个页面,我们也可以下载ca.pem和sub.class1.server.ca.pem文件,上传他们到根目录。

现在,我们的ssl可以与网站相联系起来了。

最后需要记住的:

请谨记最后一步,并确保所有的目录(上图中指出来的部分)按照我们的isp或本地服务器的规则来命名,且记住每30天验证一次域名以可以继续使用免费的ssl证书提供的安全保护措施。

本文译自makeuseof

利用qq邮箱中的随身盘实现电脑、手机互传文件

2010年05月11日 分类目录 :android技术| web技术 0

有时候,我需要下载些文件到手机上,用手机上网下载又费时又费钱,那就只能用电脑上网下载,然后再通过数据线传到手机上了。但是,如果身边刚好没有数据线怎么办?问周围的朋友借用下?万一他们也没呢?岂不是没辙了吗?现在,我想说的是,这样尴尬全都不复存在了,我们可以用qq邮箱中集成的随身盘来实现这个转移。 » 阅读全文

, ,