北京总部

全面理解HTTP

全面理解HTTP

2016-12-21

引言:作为一名软件工程Web专业学生,对于HTTP的熟悉掌握是必不可少的,特此做记录,打造自己的HTTP栈。 URL与URI 我们经常接触到的就是URL了,它就是我们访问web的一个字符串地址,那么URI是什么呢?他们是什么关系呢? URL:uniform resource location 统一资源定位符 URI:uniform resource identifier 统一资源标识符 这也就是说,URI是一种资源的标识;而URL也是一种URI,也是一种资源的标识,但它也指明了如何定位Locate到这个资源。 URI是一种抽象的资源标识,既可以是绝对的,也可以是相对的。但是URL是一种URI,它指明了定位的信息,必须是绝对的。 报文-通信的桥梁 客户端和服务器端通过相互发送报文进行通信,要深刻理解HTTP协议,就需要理解报文的格式和内容。 报文的组成 无论是请求报文还是响应报文都需要有报文首部,当然报文主体并不是必需的。 一般来说,请求报文的格式如下: 看一下百度网站的请求报文: 简单的报文形式: GET / HTTP/1.1    //请求行,包含用于请求的方法,请求的URI,HTTP版本 //以下为各种首部字段 Host: www.baidu.com Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0... Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8 响应报文的格式如下: 看一下百度网站的响应报文: HTTP/1.1 200 OK   //状态行,包含表明响应结果的状态码,原因短语和HTTP版本 //以下为各种首部字段 Server: bfe/1.0.8.5 Date: Tue, 06 Oct 2015 14:48:28 GMT Content-Type: text/html;charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Cache-Control: private 告知服务器意图的HTTP方法 发送HTTP的方法有许多种,最常用的便是GET和POST,下面就这两种进行详细地说明。 1、GET GET方法用来请求访问URI所指定的资源,(我想访问你的某个资源)并不对服务器上的内容产生任何作用结果;每次GET的内容都是相同的。GET方式把请求所需要的参数放到URL中,直接就可以在URL中看见,有大小限制。 2、POST POST方法用来传输实体主体,目的并不是获取响应的主体内容,(我要把这条信息告诉你),POST方式则是把内容放在报文内容中,因此只要报文的内容没有限制,它的大小就没有限制。 3、总结 GET用于获取某个内容,POST用于提交某种数据请求。 按照使用场景来说,一般用户注册的内容属于私密的,这应该使用POST方式;而针对某一内容的查询,为了快速的响应,可以使用GET方式。 无状态协议与Cookie HTTP是一种无状态协议,也就是每一次发送都是一次新的开始,服务器并不知道也没有必要知道当前连接的客户端是否之前有过交集,那么当需要进行保存用户登录状态时,则出现了麻烦,这个时候使用Cookie来保存状态。 Cookie会根据服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段,通知客户端保存Cookie(保存在自己的电脑里),当下次客户端发送请求时,Cookie值会被添加到请求报文中发送出去。 持久连接 使用浏览器浏览一个包含多张图片的HTML页面时,浏览器会发起多次请求,如图所示: 显而易见每次请求会造成无谓的TCP连接建立和断开,增加通信量的开销。 引入持久连接 持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。目前HTTP/1.1中默认为持久连接。 Connection:keep-alive 管线化 管线化可以同时并行发送多个请求,不需要一个一个等待响应了。 常见的状态码 确保安全的HTTPS HTTP+加密+认证+完整性保护 = HTTPS 一些登陆界面和购物结算界面使用HTTPS通信,也就是改用https://,HTTPS说简单点就是它的通信接口部分被SSL和TLS协议代替而已。 身份认证 有一些网址或者服务需要用户的身份信息,因此需要随时知道这些消息,但是肯定不能每次都让用户输入用户密码,因此关于认证就有下面几种方式: 在这里主要说一下FormBase认证,也就是表单认证。 使用Cookie来管理Session 1、客户端把用户IE和密码等登录信息放入报文的实体部分,以POST方式发送给服务器。 2、服务器进行身份认证,产生SessionID,加入到Set-Cookie内,返回给客户端。/3、客户端接收到SessionID后,将其加入Cookie,下次请求时,浏览器会自动发送Cookie。 在传输过程中,一种安全地保存密码方式是,先利用给密码加盐的方式增加额外信息,再使用散列hash函数计算出散列值后保存。 更多技术方面问题欢迎进入技术知识库~

更多>
无需内测账号,带你体验微信小程序完整开发

无需内测账号,带你体验微信小程序完整开发

2016-12-21

前一阵子的微信小程序火爆了网络与朋友圈,迅速成为讨论焦点,大家可能觉得只有收到内测邀请才能体验小程序的开发流程,其实不然,每个人都可以体验,下面就请跟着小卓一起去了解下吧。 一、下载微信Web开发工具 首先,微信给我们提供了它自己的小程序集成开发工具,只需要到这个页面下载即可:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1474644089359 下载完成后,打开开发者工具,会有一个扫码登录界面。 用你的微信扫码就可以登录进来了, 然后开发者工具会帮我们创建一个默认工程,项目的文件结构如下: 所有的代码编辑以及运行预览都可以在这个开发者工具中进行。接下来咱们看看微信小程序的项目结构。 二、项目结构 如上图,首先在根目录中有三个文件 app.js, app.json, app.wxss。 其中 app.js 是程序主入口的脚本文件, app.json 是全局配置文件, app.wxss 是小程序的样式表文件。 先来看看 app.json : 这个配置文件中定义了两个节点, pages 是小程序的所有页面对应的路径, window 是小程序窗口的配置信息。 再来看看样式文件 app.wxss : 咱们先不用深究它具体定义了什么样式,只需要先了解项目结构即可。接下来再来看看程序的主入口 app.js: 这里初始化了一个 App 对象,并且定义了三个方法 onLaunch,getUserInfo 和 globalData。先来看看 onLaunch: 首先 wx.getStorageSync 方法会获得本地的一个以 logs 为 key 的缓存数据。 传入这个方法的 logs 本身没有任何特殊含义,只是用于表示我们使用的缓存数据。 这个机制可以理解为和 iOS 的 NSUserDefaults 类似。 然后,我们想这个缓存数组中插入当前的日期 logs.unshift(Date.now())。 最后再调用 setStorageSync 方法将我们新的缓存内容写入到本地缓存中。 因为 onLaunch 方法是小程序的生命周期方法,所以在小程序启动的时候就会调用它,并将当前启动的日期记录并写入本地缓存中。 没错 onLaunch 整个方法就干了这件事儿。 我们再来看下 getUserInfo 方法,它通过调用 wx.login 和 wx.getUserInfo 两个微信平台的函数获取当前用户登录信息,并传会给回调函数 cb: 至于最开始的 if 判断 if(this.globalData.userInfo) 咱们暂时不用深究,只看 else 部分即可。 三、页面结构 了解完根目录的几个文件, 咱们再来看看页面文件, 正如咱们刚开始截图中看到的项目结构: 所有的页面都在 pages 文件夹中。 我们这个示例工程中有两个页面 index 和 logs。 还记得我们前面在 app.json 看到的页面配置吗: 正好对应上咱们现在看到的两个目录, 还要记得一点, pages 数组中的第一个元素会作为我们小程序的主页。 切记,index 页面之所以是首页,是因为它是 pages 里面的第一个元素, 而不是因为它的名称是 index。 我们来看看 index 页面的构成, index.js, index.wxml, index.wxss。 index.js 是页面的脚本文件, index.wxml 是页面的 UI 文件, index.wxss 是页面的样式文件。 先看一下 index.js: getApp() 方法获取我们的 app 实例。 然后在看 onLoad 方法, 使用我们刚才提到的 getUserInfo 方法获取用户信息,并设置到 data 属性中。 bindViewTap 方法会绑定一个事件,这个事件调用 wx.navigateTo 方法。 这个方法其实就是页面跳转,从代码中也不难看出,跳转到了 logs 页面。 脚本文件就这些内容了,咱们继续再来看看 UI 文件, index.wxml: 这个就是小程序 index 页面的 UI 文件了,其实就是微信平台定义了一系列组件,最外层是  还记得 container 么? 我们在最外层的 app.wxss 定义了它的样式。 它里面包含了两个 View。 先来看看第一个: 首先 bindtap="bindViewTap" 给这个 View 绑定了一个点击事件,也就是我们前面 index.js 对应的这个方法,用户点击这个 View 就会跳转到 logs 页面上。 然后这个 View 里面包含了一个 Image 和 Text, Image 的 src 属性设置为userInfo.avatarUrl, 代表当前用户的头像, Text 中使用 userInfo.nickName, 代表当前用户的昵称。 这样, index 页面的整体逻辑就都完成了, 还有一个 index.wxss 样式文件,这个咱们就先略过。 再来看看第二个视图: motto 其实就是我们在 index.js 中定义的一个属性: 它会在页面上显示一个 Hello World。 现在,我们切换到调试界面, 就可以看到小程序的主页了, 和我们刚刚描述的 UI 完全一样吧: 这里的用户头像和昵称是动态从你的登录状态中取到的。 然后我们在这里点击用户的头像,就会跳转到 logs 页面, 列出你每次登录小程序的时间点。 四、上传小程序 现在微信小程序的基本开发流程就给大家介绍完了,还有一个 logs 页面没介绍,但它和 index 的页面的基本思路都是一样的,咱们就不多赘述了。 开发完小程序后,我们需要把它部署到哪里呢? 相信大家也有同样的问题。 答案也很简单,切换到项目选项卡,然后点击上传按钮即可: 由于笔者的环境没有内测账号,所以在上传区域显示的是项目未关联 AppID, 如果有了测试账号,就会显示你的 AppID 了。 目前只有内测账号才能够上传小程序。这就是唯一的差别了。没有内测账号只是不能上传,但完全可以在本地开发和测试。 小程序的这种上传方式可能会让大家觉得有些不同吧。 大家平常理解的 Web app 一般都需要自己搭建服务端,并且维护。 而小程序的这种托管方式,其实已经和我们开发一个原生 App 差不多了。 虽然前端上使用的是 js 这些看起来像是 web 的技术,但它核心思路跟传统的 web app 已经不太一样。 更像一种类似 React Native 的实现。 五、结尾 这次和大家一起,从头到尾完整的体验了一个最简单的小程序的整体结构以及开发思路。如果能找到合适的切入点,小程序这个平台还是能找到一些不错的机会的。但不要认为小程序的出现就会马上颠覆谁,也不需要听到网上有人说小程序难成大事就觉得它没机会。 找到自己擅长的,以及用户需要的,没准就会创造出一些不错的产品。 这次也是帮大家做一个基本的技术梳理,希望能够对大家有所帮助。

更多>
郭老师说:专业UI设计师需要注意什么

郭老师说:专业UI设计师需要注意什么

2016-12-14

       今天,小卓请到了中软卓越大连ETC郭毓舒老师为大家带来APP界面和UI设计界面的知识。郭老师毕业于吉林艺术学院的视觉传达设计专业,具有10多年的从业经验,是一名资深设计师哦。快跟小卓一起涨姿势吧! UI设计普遍存在的问题: ·缺乏对细节的注意,图形和配色风格前后的统一性不够。 ·图标内容的大小和配色颜色的选择范围的匹配度不高。 ·界面设计视觉动点视觉交点界面风格混乱,乱用色彩搭配。 ·人机交互设计不能充分了解用户的心理需求和感觉规律。 ·背景的层次感形态统一性不强,缺少简洁精致的舒适美。 ·原创性差,可以借鉴其他的设计,但是不能直接抄,注意版权问题。 科学合理的设计流程 Step1:确定意向        确定风格,根据APP的主题确定设计风格,达到突出主题的目的。 环保可以采用蓝色的和绿色的清新风格,也可以选择警醒的灰色风格。 Step2:找到参考        可以到知名设计网站,观察研习国内外知名大师的设计作品,确定APP风格与控件元素的匹配度。 Step3:整体设计        要考虑到设计的人机交互,考虑到整套风格的色系,注重用户的使用感觉,根据APP的功能和之前设定的风格出整体的草图。 Step4:电脑绘图        开始在电脑上绘图,绘图过程中当调整某一模块和控件的风格及配色时也要考虑到整体风格和色彩的匹配度和融合度。 可借鉴素材网站:        Dribble、UI中国、站酷、UI设计、花瓣网等。

更多>
每个程序员都需要了解的一个SQL技巧

每个程序员都需要了解的一个SQL技巧

2016-12-14

 对于数据过滤而言CHECK约束已经算是相当不错了。然而它仍存在一些缺陷,比如说它们是应用到表上面的,但有的时候你可能希望指定一条约束,而它只在特定条件下才生效。使用SQL标准的WITH CHECK OPTION子句就能完成这点,至少Oracle和SQL Server都实现了这个功能。下面是实现方式:       CREATE TABLE books (           id      NUMBER(10)              NOT NULL,           title     VARCHAR2(100 CHAR)     NOT NULL,           price    NUMBER(10, 2)            NOT NULL,           CONSTRAINT pk_book PRIMARY KEY (id)  ); / CREATE VIEW expensive_books AS SELECT id, title, price FROM books WHERE price > 100 WITH CHECK OPTION;  / INSERT INTO books VALUES (1, '1984', 35.90);   INSERT INTO books VALUES(      2,     'The Answer to Life, the Universe, and Everything',      999.90 );       正如你看到的那样,expensive_books 是那些价格大于100块的书。这个视图只会返回第二本书:       SELECT * FROM expensive_books;       上述查询的输出是:        ID   TITLE                                    PRICE --   --------------------------------------------   -------        2    The Answer to Life, the Universe, and ...    999.9       不过由于我们使用了CHECK OPTION,我们还能防止用户往”昂贵的书籍”中插入那些廉价的。比如说,我们运行下这个查询:        INSERT INTO expensive_books VALUES (        3,        '10 Reasons why jOOQ is Awesome',        9.99 ); 更多信息知识库内容请点击:信息知识库

更多>
Java中的main()方法详解

Java中的main()方法详解

2016-11-21

在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等。 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这个例子说明Java类中main()方法的奥秘,程序的代码如下:   public class HelloWorld { public static void main(String args[]) { System.out.println("Hello World!"); } }   一、先说类: HelloWorld 类中有main()方法,说明这是个java应用程序,通过JVM(java虚拟机)直接启动运行的程序。 既然是类,java允许类不加public关键字约束,当然类的定义只能限制为public或者无限制关键字(默认的)。 二、再说main()方法 main()方法的声明为:public staticvoid main(String args[])。必须这么定义,这是Java的规范。 为什么要这么定义,和JVM的运行有关系。 当一个类中有main()方法,执行命令“java 类名”则会启动虚拟机执行该类中的main方法。 由于JVM在运行这个Java应用程序的时候,首先会调用main方法,调用时不实例化这个类的对象,而是 通过类名直接调用因此需要是限制为publicstatic。 对于java中的main方法,JVM有限制,不能有返回值,因此返回值类型为void。 main方法中还有一个输入参数,类型为String[],这个也是java的规范,main()方法中必须有一个入参,类细必须String[],至于字符串数组的名字,这个是可以自己设定的,根据习惯,这个字符串数组的名字一般和Sun Java规范范例中mian参数名保持一致,取名为args。 因此,main()方法定义必须是:“public static voidmain(String[] args)”

更多>
关于Python,你需要了解的一些优雅技

关于Python,你需要了解的一些优雅技

2016-11-16

Python具有丰富和强大的库。它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。Python让代码具备高度的可阅读性且看起来整洁美观。它不像其他的静态语言如C、Pascal那样需要重复书写声明语句,也不像它们的语法那样经常有特殊情况和惊喜。下面就来一起了解下Python的优雅技巧。

更多>
为什么要用Spring(含三大框架简介)

为什么要用Spring(含三大框架简介)

2016-11-02

 Spring作为三大框架之一,一直困惑她有什么用?为什么要使用Spring呢?(大部分来自网上,引用出处太多,恕不一一标明。)。        SSH在J2EE项目中表示了3种框架,即 Spring + Struts +Hibernate。 Struts对Model,View和Controller都提供了对应的组件。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,可以应用在任何使用JDBC的场合,可以在Servlet/JSP的Web应用中使用,也可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。        Struts2原理就是用拦截器,使得你客户端发送的请求都被拦截下来后处理。拦截器用到了反射机制。Struts2主要的功能是控制转发,在于Action的处理,和struts.xml配置。        Spring其实包含了很多的知识,用到的有IOC,AOP等,其实就是一个管理框架的容器,你不用再考虑你new对象了,它会帮你做,降低了层与层之间的耦合度。Spring里面有很多的思想,IOC就是控制反转,注入。AOP是面向切面的,有点像拦截器。       Hibernate是持久层框架,我们平时用JDBC操作数据库要写SQL语句,有时候字段一多会很麻烦,于是用hibernate就很方便了,你只要熟练掌握里面的映射关系,就不用写sql语句了,它会帮你写,API调用一下很方便的。 Struts 1.Struts框架结构       Struts对Model,View和Controller都提供了对应的组件。       在右图中,ActionServlet,这个类是Struts的核心控制器,负责拦截来自用户的请求。       Action,这个类通常由用户提供,该控制器负责接收来自ActionServlet的请求,并根据该请求调用模型的业务逻辑方法处理请求,并将处理结果返回给JSP页面显示。        2.Model部分        由ActionForm和JavaBean组成,其中ActionForm用于封装用户的请求参数,封装成ActionForm对象,该对象被ActionServlet转发给Action,Action根据ActionForm里面的请求参数处理用户的请求。        JavaBean则封装了底层的业务逻辑,包括数据库访问等。        3.View部分        该部分采用JSP实现。        Struts提供了丰富的标签库,通过标签库可以减少脚本的使用,自定义的标签库可以实现与Model的有效交互,并增加了现实功能。对应上图的JSP部分。        4.Controller组件        Controller组件有两个部分组成——系统核心控制器,业务逻辑控制器。        系统核心控制器,对应上图的ActionServlet。该控制器由Struts框架提供,继承HttpServlet类,因此可以配置成标注的Servlet。该控制器负责拦截所有的HTTP请求,然后根据用户请求决定是否要转给业务逻辑控制器。        业务逻辑控制器,负责处理用户请求,本身不具备处理能力,而是调用Model来完成处理。对应Action部分。        Spring 1.简介        ◆目的:解决企业应用开发的复杂性        ◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能        ◆范围:任何Java应用        简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。        2.轻量        从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。        此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。        3.控制反转        Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。        4.面向切面        Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。        应用对象只实现它们应该做的——完成业务逻辑——仅此而已。        它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。        5.容器        Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。        然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。        6.框架        Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。        所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。        Hibernate 1.简介        Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。        Hibernate的核心接口一共有5个,分别为:Session、SessionFactory、Transaction、Query和Configuration。这5个核心接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。下面对这五个核心接口分别加以介绍。        2.Session接口        Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSesion对象称为用户session。        3.SessionFactory接口        SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。        4.Configuration接口        Configuration接口负责配置并启动Hibernate,创建SessionFactory对象。在Hibernate的启动的过程中,Configuration类的实例首先定位映射文档位置、读取配置,然后创建SessionFactory对象。        5.Transaction接口        Transaction接口负责事务相关的操作。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。   6.Query和Criteria接口       Query和Criteria接口负责执行各种数据库查询。它可以使用HQL语言或SQL语句两种表达方式。   作者: weibo_尉广明大将军_0 链接:http://www.imooc.com/article/7283 来源:慕课网

更多>
10个jQuery小技巧

10个jQuery小技巧

2016-11-02

1. 禁止右键点击 $(document).ready(function(){     $(document).bind("contextmenu",function(e){         return false;     }); }); 2. 隐藏搜索文本框文字 $(document).ready(function() { $("input.text1").val("Enter your search text here");    textFill($('input.text1')); });     function textFill(input){ //input focus text function      var originalvalue = input.val();      input.focus( function(){           if( $.trim(input.val()) == originalvalue ){ input.val(''); }      });      input.blur( function(){           if( $.trim(input.val()) == '' ){ input.val(originalvalue); }      }); } 3. 在新窗口中打开链接 $(document).ready(function() {    //Example 1: Every link will open in a new window    $('a[href^="http://"]').attr("target", "_blank");    //Example 2: Links with the rel="external" attribute will only open in a new window    $('a[@rel$='external']').click(function(){       this.target = "_blank";    }); }); // how to use open link 4. 检测浏览器 $(document).ready(function() { // Target Firefox 2 and above if ($.browser.mozilla && $.browser.version >= "1.8" ){     // do something } // Target Safari if( $.browser.safari ){     // do something } // Target Chrome if( $.browser.chrome){     // do something } // Target Camino if( $.browser.camino){     // do something } // Target Opera if( $.browser.opera){     // do something } // Target IE6 and below if ($.browser.msie && $.browser.version <= 6 ){     // do something } // Target anything above IE6 if ($.browser.msie && $.browser.version > 6){     // do something } }); 5. 预加载图片 $(document).ready(function() { jQuery.preloadImages = function() {   for(var i = 0; i

更多>

推荐阅读

更多

友情链接:

中软卓越java培训地址:北京市海淀区科学院南路2号融科资讯中心C座北楼12层 联系电话:400-666-3775 邮箱账号:etc-marketing@chinasofti.com

©2008-2016 北京中软国际教育科技股份有限公司 京ICP备14058756号-2