1、AJAX框架
jquery:属于纯粹的前台框架,比较轻量级,JavaScript语言
prototype:与jquery类似,历史比较久
dojo:页面端框架
ext:重量级页面端框架,多用于内网系统。夸张成桌面
dwr:JavaScript调用java,不提供页面效果
-
-
- var xmlhttp;
- function verify(){
-
-
-
- var username = document.getElementById("username").value;
-
-
-
-
- if (window.XMLHttpRequest){
-
- xmlhttp = new XMLHttpRequest();
-
- if (xmlhttp.overrideMimeType){
- xmlhttp.overrideMimeType("text/xml");
- }
- }else if (window.ActiveXObject){
-
-
-
- var activexName = ["MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
- for (var i =0;i<activexName.length;i++){
- try{
-
-
- xmlhttp = new ActiveXObject(activexName[i]);
- break;
- }catch(e){
- }
- }
- }
-
-
- if (!xmlhttp){
- alert("XMLHttpRequest对象创建失败!!");
- return;
- }else{
- alert(xmlhttp);
- }
-
-
-
-
- xmlhttp.onreadystatechange = callback;
-
-
-
-
-
- xmlhttp.open("GET","AjaxServletDemo1?username="+username,true);
-
-
-
-
- xmlhttp.send(null);
- }
-
-
- function callback(){
-
-
- if (xmlhttp.readyState == 4){
-
- if (xmlhttp.status == 200){
-
-
- var responseText = xmlhttp.responseText;
-
-
- var spanNod = document.getElementById("result");
- spanNod.innerHTML = responseText;
- }
- }
- }
XMLHttpRequest对象的属性:
属性 | 说明 |
readyState | readyState一改变,回调函数就调用 表示XMLHttpRequest对象的状态: 0:未初始化。对象已创建,未调用open; 1:open方法成功调用,但Send方法未调用; 2:send方法已经调用,尚未开始接受数据; 3:正在接受数据。Http响应头信息已经接受,但尚未接收完成; 4:完成,即响应数据接受完成。 |
Onreadystatechange | 请求状态改变的事件触发器(readyState变化时会调用这个属性上注册的JavaScript函数)。 |
responseText | 服务器响应的文本内容 |
responseXML | 服务器响应的XML内容对应的DOM对象 |
Status | 服务器返回的http状态码。200表示“成功”,404表示“未找到”,500表示“服务器内部错误”等。 |
statusText | 服务器返回状态的文本信息。 |
方法 | 说明 |
Open(string method, string url, boolean asynch, String username, string password) | 指定和服务器端交互的HTTP方法,URL地址,即其他请求信息; Method:表示http请求方法,一般使用"GET","POST". url:表示请求的服务器的地址; asynch:表示是否采用异步方法,true为异步,false为同步; 后边两个可以不指定,username和password分别表示用户名和密码,提供http认证机制需要的用户名和密码。 |
Send(content) | 向服务器发出请求,如果采用异步方式,该方法会立即返回。 content可以指定为null表示不发送数据,其内容可以是DOM对象,输入流或字符串。 |
SetRequestHeader( String header,String Value) | 设置HTTP请求中的指定头部header的值为value. 此方法需在open方法以后调用,一般在post方式中使用。 |
getAllResponseHeaders() | 返回包含Http的所有响应头信息,其中相应头包括Content-length,date,uri等内容。 返回值是一个字符串,包含所有头信息,其中每个键名和键值用冒号分开,每一组键之间用CR和LF(回车加换行符)来分隔! |
getResponseHeader(String header) | 返回HTTP响应头中指定的键名header对应的值 |
Abort() | 停止当前http请求。对应的XMLHttpRequest对象会复位到未初始化的状态。 |
2、XMLHttpRequest的XML交互
服务器端:
- package seu.xinci.servlet;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
-
-
-
-
-
- @WebServlet(name = "AjaxServletDemo2",urlPatterns = {"/AjaxServletDemo2"})
- public class AjaxServletDemo2 extends HttpServlet {
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- response.setContentType("text/xml;charset=UTF-8");
-
- String username = request.getParameter("username");
- PrintWriter out = response.getWriter();
-
-
- StringBuilder sb = new StringBuilder();
- sb.append("<message>");
- if (username == null || username.trim().equals("")){
- sb.append("用户名不能为空").append("</message>");
- }else {
- if (username.equals("aaa")){
- sb.append("该用户已存在,不能进行注册").append("</message>");
- }else {
- sb.append("该用户名可以注册").append("</message>");
- }
- }
- out.write(sb.toString());
- }
- }
js:
GET和POST的区别:
“GET”和“POST”的一个重要区别在于,“GET”方式传递给服务器的信息一般以后缀参数方式存在于URL地址中,而URL的长度通常都有限制,这也就限制了“GET”方式传递给服务器的内容大小
而“POST”方式传递给服务器的信息并不位于URL地址中,所以没有大小限制。
通常我们在服务器端的Servlet中,doGet和doPost做的是一样的工作,因此由于POST传递信息没有大小限制,我们实际应用中比较多的会使用POST。
- xmlhttp.open("GET","AJAXServer?name=" + encodeURI(encodeURI(name)),true);
- xmlhttp.send(null);
- xmlhttp.open("POST","AJAXServer",true);
- xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
- xmlhttp.send("name=" + encodeURI(encodeURI(name)));
每次readyState变化时onreadystatechange属性对应的函数都会被调用。
之前我们曾经说过onreadystatechange属性设置回调函数是为了在接收到响应数据后对响应数据进行处理,之所以这样说是因为我们通常只关心收到响应数据以后时的工作,也就是readyState=4时的状态,因此我们的回调函数中也用readyState==4来做判断。
status和statusText属性:
它的值是http的状态码,我们通常只在status=200时才进行响应数据处理,但也可根据具体情况在status为其他值时做一些处理。
statusText属性一般用于status不为200时显示详细的http错误状态信息
responseText与responseXML属性:
无论服务器端返回的是XML还是普通的文本内容,html内容,都可以使用responseText属性来获得服务器端的返回值。
当服务器端返回的不是XML内容是,不同的浏览器在获取responseXML属性值时略有不同,IE仍然会获取到一个DOM对象,只不过内容是空的,而FireFox获取到的则是一个null
需要注意的内容:
- 1.不同浏览器下XMLHttpRequest对象的不同的建立方式
- 2.设置回调函数时不要加括号
- 3. open方法三个参数含义,此外还需要注意GET方式和POST方式服务器端地址的不同写法
- 4. GET方式和POST方式send的参数的不同之处,以及POST方式下send之前需要设置请求头信息的工作
- 5.如何判断正确的响应数据已经返回,此外还要注意如何获取响应数据内容。
4、Jquery的XML交互
- function verify(){
- var username = $("#username").val();
-
- $.ajax({
- type:"POST",
- url:"AjaxServletDemo2",
- data:"username="+username,
- dataType:"xml",
- success:callback
- })
- }
-
- function callback(data){
-
- var jqueryObj = $(data);
-
- var message = jqueryObj.children();
-
- var text = message.text();
-
- var resultObj = $("#result");
- resultObj.html(text);
-
- }
5、浏览器缓存问题
IE:若url地址未变,则读取缓存信息。
给URL地址增加时间戳,骗过浏览器
- function verify() {
-
-
- var url = "AJAXServer?name=" + encodeURI(encodeURI($("#userName").val()));
- url = convertURL(url);
- $.get(url,null,function(data){
- $("#result").html(data);
- });
- }
-
-
- function convertURL(url) {
-
- var timstamp = (new Date()).valueOf();
-
-
- if (url.indexOf("?") >= 0) {
- url = url + "&t=" + timstamp;
- } else {
- url = url + "?t=" + timstamp;
- }
- return url;
- }
换验证码!!
6、中文乱码与跨域调用
中文乱码问题:编码统一问题
1、本页面编码
2、发送内容的编码 jquery中利用encodeURL 内部默认使用的是UTF-8
3、接收信息的编码 request.setCharacterEncoding("UTF-8")
4、返回数据的编码 response.setContentType("text/html;charset=UTF-8")
跨域访问:
XMLHttpRequest的一个特殊安全问题:
IE:访问跨域页面时会给出提示,用户确认后会访问
Mozilla FireFox及其他:不允许访问跨域页面
如何解决跨域访问:
浏览器端:
在浏览器端的代码中,我们需要在调用open方法之前判断一下要连接的地址是不是以http开头的,如果是则认为要访问的是跨域的资源,首先将当前url中的”?”变成”&”,这是因为将要连接的地址改为”Proxy?url=” + url以后,如果原来url地址中有参数的话,新的url地址中就会有两个“?”这会导致服务器端解析参数错误,”url=”之后的内容表示本来要访问的跨域资源的地址。
- function convertURL(url){
- if(url.substring(0,7) == "http://"){
- url = url.replace("?","&");
- url = "Proxy?url=" + url;
- }
- return url;
- }
代理端:
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.io.OutputStreamWriter;
- import java.net.*;
- import java.util.Enumeration;
-
- public class Proxy extends javax.servlet.http.HttpServlet {
- protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
- throws javax.servlet.ServletException, java.io.IOException {
- response.setContentType("text/html;charset=GB2312");
- String url = request.getParameter("url");
- StringBuffer param = new StringBuffer();
- Enumeration enu = request.getParameterNames();
- int total = 0;
- while(enu.hasMoreElements()){
- String name = (String)enu.nextElement();
- if(!name.equals("url")){
- if(total == 0){
- param.append(name).append("=").append(URLEncoder.encode(request.getParameter(name),"UTF-8"));
- } else{
- param.append("&").append(name).append("=").append(URLEncoder.encode(request.getParameter(name),"UTF-8"));
- }
- total++;
-
- }
- }
- PrintWriter out = response.getWriter();
- if(url != null){
- URL connect = new URL(url.toString());
- URLConnection connection = connect.openConnection();
- connection.setDoOutput(true);
- OutputStreamWriter paramout = new OutputStreamWriter(connection.getOutputStream());
- paramout.write(param.toString());
- paramout.flush();
- BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"GB2312"));
- String line;
- while((line = reader.readLine()) != null){
- out.println(line);
- }
- paramout.close();
- reader.close();
- }
-
- }
- protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
- response.setContentType("text/html;charset=GB2312");
- StringBuffer url = new StringBuffer();
- url.append(request.getParameter("url"));
- Enumeration enu = request.getParameterNames();
- int total = 0;
- while(enu.hasMoreElements()){
- String name = (String)enu.nextElement();
- if(!name.equals("url")){
- if(total == 0){
- url.append("?").append(name).append("=").append(URLEncoder.encode(request.getParameter(name),"UTF-8"));
- } else{
- url.append("&").append(name).append("=").append(URLEncoder.encode(request.getParameter(name),"UTF-8"));
- }
- total++;
-
- }
- }
- PrintWriter out = response.getWriter();
- if(url != null){
- URL connect = new URL(url.toString());
- BufferedReader reader = new BufferedReader(new InputStreamReader(connect.openStream(),"GB2312"));
- String line;
- while((line = reader.readLine()) != null){
- out.println(line);
- }
- reader.close();
- }
-
- http:
- Proxy?url=http:
-
- url=http:
-
- http:
-
-
- }
- }
注意Proxy中针对GET方式和POST方式进行了分别的处理,其中GET方式仍然将参数信息拼到URL中,而POST方式则向HttpURLConnection的数据流中添加参数信息。
由于对本来请求的地址和其包含的参数进行了转换,导致url参数中只包含原来请求的地址信息,而原来请求的参数信息则需要我们解析出来和地址信息一起重新组成本来的请求URL,因此方法开头的一段while就做了这个工作。
注意由于进入servelt之前参数信息已经被做过一次URLDecoder,因此这个时候参数信息中的中文信息传到真正要访问的servlet时解码会出现乱码,因此我们再拼接参数信息之前又再一次通过URLEncoder.encode方法对所有参数信息进行了一次编码,这样就解决了中文的乱码问题。
在从远端服务器读取数据时,要显示的指定输入流的编码格式,这样才可以保证通过BufferReader读到的内容不会有乱码信息。