=================================================
本文为khler原作,转载必须确保本文完整并完整保留原作者信息及本文原始链接
E-mail: khler@163.com
QQ: 23381103
MSN: pragmac@hotmail.com
=================================================
Ajax 就是异步的JavaScriptXML(Asynchronous JavaScript and XML),就是在JavaScript中利用XMLHttpRequest对象直接与服务器进行异步通信以更新页面的局部信息而不用刷新整个页面的机制;由于它是局部更新,所以速度更快;由于利用现有的、标准的数据交换协议(HTTP请求),所以它是独立于Web服务器、浏览器的。
理解Ajax的关键就是JavaScrip脚本本身和XMLHttpRequest对象。
2008.10.27
几个Ajax应用需要注意的事项
shiny是 两年前开始接触Ajax的,那时候的Ajax支持还不是很好,都要涉及底层,没有现成的框架给你调用。现在把常见的问题列举如下。
1、编码问题
注意AJAX要取的文件是UTF-8编码的。GB2312编码传回BROWSE后中文会乱码。如果用VBScript的话还可以转化,但是VBScript只有IE支持。
所以,选择UTF-8编码是一劳永逸的办法。
2、清除服务器端文件的缓存。
当用XMLHTTP取回一个服务器端的文件,文件会缓存在浏览器端。下次再取文件时,不会再去服务器取文件。所以,对于刷新频繁的文件,一定要指定文件的过期时间。
3、什么时候使用XML
Ajax里的X指的就是XML,可是真的XML就是最好的解决方案吗?XML和JSON相比,在传递同等量的信息时,XML文件更大。所以往往 JSON是更好的选择。不过,你还可以直接输出Javascript执行,这样的效率往往更高:不需要写复杂的回调函数。不过安全问题也要更加注意。
4、两种Ajax的方式
一些人的基础可能还不是很扎实,并不非常了解Ajax的原理,那你知道Ajax由哪两种方式来实现吗?
最古老的一种是iframe来加载一个包含js的网页,这个网页里的脚本用 top.function来调用parent页面里的函数。但是,你可以指定a的target和form的target,这样就不用序列化表单,实际上能 很方便地发送表单。当然后期就稍微有点麻烦,出现问题也不容易解决。
后来就是xmlhttp组件的方式。什么时候挑选什么方式,这也是一种技巧。
5、跨域问题
如果一个脚本不在同一个域,两者就不能相互调用。如果iframe里是其他域的网页,就不能访问parent页的具体内容。如果需要访问远程的 XML,比如RSS FEED,建议可以用服务器端脚本来中转。在访问量不是非常大的情况下还是很很好的一个解决办法。不过,翻阅JQuery手册发现它能调用(执行)跨域的 脚本,具体怎么做的还不是很清楚。大家可以下载JQUERY未加密的版本来研究下。
6、安全问题
在服务器端,虽然客户端能预处理很多东西,你仍要注意一句话:一切来自客户端的变量都是有害的。不在Ajax的情况下很多程序员往往会放松警惕。这使得安全问题更隐蔽。如果是开源程序的话那么问题就会在网友面前马上暴露出来;黑盒的情况下,往往被入侵了还是找不出原因。
结语:实际上在这个框架横行的年代直接编写Ajax实现代码的机会并不多,很多JS框架都集成了AJAX调用函数,一些服务器端的框架,例如 THINKPHP也集成了AJAX。但是,理解一些底层的东西,还是有利于排除BUG,提高AJAX应用的性能的。俺是 shiny,QQ416697586,个人网站http://www.daijie.info/,欢迎和我交流
2008.10.30 上午
Ajax/Json客户/服务端不能正确取得数据的问题
客户端:
服务端接受数据:
发现客户端提交Json数据,服务端Json解析到空数据对象;或者相反的情况,服务端正确返回数据给客户端,但客户端获取空数据。通过FireBug工具查看,发现发送方正确发出,但接收方得到的是空,由此可以推断是中间数据转换/映射时出现了问题。
结论:一般有两种情况导致这种情况发生:
1、Json映射表中有某些字段类型不匹配;
2、当前数据库中已有数据与Json映射表中的某些字段类型不匹配。
这两个问题都很隐蔽,但是第二种情况尤其不容易发现,现总结于此,希望对大家有所帮助!
—— He YuanHui
2008.10.30
3、今天碰到了第三种情况:服务函数返回了数据,但是客户端接收到的数据为空
Json在做数据序列化的时候,如果没有使用DataMember标签,那么默认匹配所有属性,一旦有一个属性不匹配,则返回为空。有时候我们只关心一个对象的某几个属性,所以往往在客户端申明Ext.data.JsonReader()时只申明几个关心的属性,从而导致不能正确接收数据的情况发生。
解决办法是在服务端的类申明上打上[DataContract]标签,同时在关心的几个属性上打上[DataMember]标签,这样,在Json序列化时便只系列化匹配被标注的属性:
[Table(Name="dbo.hole")]
[DataContract]
public partial class Hole : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private System.Guid _id;
private System.Guid _surveyid;
private string _name;
private System.Nullable<double> _height;
private System.Nullable<double> _diameter;
private System.Nullable<double> _depth;
private System.Nullable<System.DateTime> _addedtime;
//.
//.
public Hole()
{
this._Survey = default(EntityRef<Survey>);
OnCreated();
}
[Column(Storage="_id", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
public System.Guid id
{
get
{
return this._id;
}
set
{
if ((this._id != value))
{
this.OnidChanging(value);
this.SendPropertyChanging();
this._id = value;
this.SendPropertyChanged("id");
this.OnidChanged();
}
}
}
[Column(Storage="_name", DbType="NChar(50)")]
[DataMember]
public string name
{
get
{
return this._name;
}
set
{
if ((this._name != value))
{
this.OnnameChanging(value);
this.SendPropertyChanging();
this._name = value;
this.SendPropertyChanged("name");
this.OnnameChanged();
}
}
}
[Column(Storage="_height", DbType="Float")]
[DataMember]
public System.Nullable<double> height
{
get
{
return this._height;
}
set
{
if ((this._height != value))
{
this.OnheightChanging(value);
this.SendPropertyChanging();
this._height = value;
this.SendPropertyChanged("height");
this.OnheightChanged();
}
}
}
[Column(Storage="_diameter", DbType="Float")]
[DataMember]
public System.Nullable<double> diameter
{
get
{
return this._diameter;
}
set
{
if ((this._diameter != value))
{
this.OndiameterChanging(value);
this.SendPropertyChanging();
this._diameter = value;
this.SendPropertyChanged("diameter");
this.OndiameterChanged();
}
}
}
[Column(Storage="_depth", DbType="Float")]
[DataMember]
public System.Nullable<double> depth
{
get
{
return this._depth;
}
set
{
if ((this._depth != value))
{
this.OndepthChanging(value);
this.SendPropertyChanging();
this._depth = value;
this.SendPropertyChanged("depth");
this.OndepthChanged();
}
}
}
[Column(Storage="_addedtime", DbType="DateTime")]
public System.Nullable<System.DateTime> addedtime
{
get
{
return this._addedtime;
}
set
{
if ((this._addedtime != value))
{
this.OnaddedtimeChanging(value);
this.SendPropertyChanging();
this._addedtime = value;
this.SendPropertyChanged("addedtime");
this.OnaddedtimeChanged();
}
}
}
//.
//.
}
Reference:
w3school: http://www.w3school.com.cn/ajax/ajax_intro.asp (W3School的文章写的很认真很浅显易懂,强烈建议初学者去看看,鉴与原链接申明,此处不做转载)
shiny blog: http://www.daijie.info/