本文为转载文章,转载地址:http://blog.csdn.net/koukou234/article/details/77647947
1、AJAX框架
//用户名校验的方法
//这个方法将使用XMLHTTPRequest对象来进行AJAX的异步数据交互
var xmlhttp;
function verify(){
//1、使用dom的方式获取文本框中的值
//document.getElementById("username")是dom中获取元素节点的一种方法,一个元素节点对应HTML中的一个标签,如<input>
//.value可以获取一个元素节点的value属性值
var username = document.getElementById("username").value;
//2、创建XMLHttpRequest对象
//这是XMLHttpRequest对象五步使用中最复杂的一步(不同浏览器的差异)
if (window.XMLHttpRequest){
//针对FireFox,Mozillar,Opera,Safari,IE7,IE8
xmlhttp = new XMLHttpRequest();
//针对某些特定版本的mozillar浏览器的BUG进行修正,不要加()
if (xmlhttp.overrideMimeType){
xmlhttp.overrideMimeType("text/xml");
}
}else if (window.ActiveXObject){
//针对IE6,IE5.5,IE5
//两个可以用于创建XMLHttpRequest对象的空间名称,保存在一个js的数组中
//排在前面的版本较新
var activexName = ["MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i =0;i<activexName.length;i++){
try{
//去除一个空间名进行创建,如果创建成功就终止循环
//如果创建失败,会抛出异常,然后可以继续循环,继续尝试创建
xmlhttp = new ActiveXObject(activexName[i]);
break;
}catch(e){
}
}
}
//确认XMLHttpRequest对象创建成功
if (!xmlhttp){
alert("XMLHttpRequest对象创建失败!!");
return;
}else{
alert(xmlhttp);
}
//2.注册回调函数
//注册回调函数时,只需要函数名,不要加()
//我们需要将函数名注册,如果加上(),就会把函数的返回值注册上,这是错误的
xmlhttp.onreadystatechange = callback;
//3.设置连接信息()共5个参数
//第一个参数表示http的请求方式,支持所有http的请求方式,主要使用get和post
//第二个参数表示请求的url地址,get方式请求的参数也在url中
//第三个参数表示采用异步还是同步方式交互,true表示异步,false同步
xmlhttp.open("GET","AjaxServletDemo1?username="+username,true);
//4.发送数据,开始和服务器端进行交互
//同步方式下,数据回来后才继续执行send后面的代码
//异步方式,send后继续执行
xmlhttp.send(null);
}
//回调函数
function callback(){
//5.接收响应数据
//判断对象的状态是否交互完成
if (xmlhttp.readyState == 4){
//判断http的交互是否成功
if (xmlhttp.status == 200){
//获取服务器端返回的数据
//获取服务器端输出的纯文本数据
var responseText = xmlhttp.responseText;
//将数据显示在页面上
//通过dom的方式找到div标签对应的元素节点
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;
/**
* Created by Administrator on 2016-3-6.
* 返回xml数据
*/
@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 {
//修改点1——text/html->text/xml
response.setContentType("text/xml;charset=UTF-8");
String username = request.getParameter("username");
PrintWriter out = response.getWriter();
//修改点2——返回的数据需要拼装成xml格式,即加上标签
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:
//用户名校验的方法
//这个方法将使用XMLHTTPRequest对象来进行AJAX的异步数据交互
var xmlhttp;
function verify(){
//1、使用dom的方式获取文本框中的值
//document.getElementById("username")是dom中获取元素节点的一种方法,一个元素节点对应HTML中的一个标签,如<input>
//.value可以获取一个元素节点的value属性值
var username = document.getElementById("username").value;
//2、创建XMLHttpRequest对象
//这是XMLHttpRequest对象五步使用中最复杂的一步(不同浏览器的差异)
if (window.XMLHttpRequest){
//针对FireFox,Mozillar,Opera,Safari,IE7,IE8
xmlhttp = new XMLHttpRequest();
//针对某些特定版本的mozillar浏览器的BUG进行修正,不要加()
if (xmlhttp.overrideMimeType){
xmlhttp.overrideMimeType("text/xml");
}
}else if (window.ActiveXObject){
//针对IE6,IE5.5,IE5
//两个可以用于创建XMLHttpRequest对象的空间名称,保存在一个js的数组中
//排在前面的版本较新
var activexName = ["MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i =0;i<activexName.length;i++){
try{
//去除一个空间名进行创建,如果创建成功就终止循环
//如果创建失败,会抛出异常,然后可以继续循环,继续尝试创建
xmlhttp = new ActiveXObject(activexName[i]);
break;
}catch(e){
}
}
}
//确认XMLHttpRequest对象创建成功
if (!xmlhttp){
alert("XMLHttpRequest对象创建失败!!");
return;
}else{
alert(xmlhttp);
}
//2.注册回调函数
//注册回调函数时,只需要函数名,不要加()
//我们需要将函数名注册,如果加上(),就会把函数的返回值注册上,这是错误的
xmlhttp.onreadystatechange = callback;
//3.设置连接信息()共5个参数
//第一个参数表示http的请求方式,支持所有http的请求方式,主要使用get和post
//第二个参数表示请求的url地址,get方式请求的参数也在url中
//第三个参数表示采用异步还是同步方式交互,true表示异步,false同步
//GET方式
//xmlhttp.open("GET","AjaxServletDemo1?username="+username,true);
//POST方式
xmlhttp.open("POST","AjaxServletDemo2",true);
//POST方式需要自己设置http的请求头
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//4.发送数据,开始和服务器端进行交互
//同步方式下,数据回来后才继续执行send后面的代码
//异步方式,send后继续执行
//GET方式
//xmlhttp.send(null);
//POST方式
xmlhttp.send("username="+username);
}
//回调函数
function callback(){
//5.接收响应数据
//判断对象的状态是否交互完成
if (xmlhttp.readyState == 4){
//判断http的交互是否成功
if (xmlhttp.status == 200){
//获取服务器端返回的数据
//使用responseXML的方式来接收XML数据对象的DOM对象
var domObj = xmlhttp.responseXML;
if (domObj) {
//获取标签节点
//<message>123123123</message>
//dom中利用getElementsByTagName可以根据标签名来获取元素节点,返回的是一个数组
var Nodes = domObj.getElementsByTagName("message");
if (Nodes.length > 0) { //获取message节点中的文本内容
//message标签中的文本在dom中是message标签所对应的元素节点的字节点,firstChild可以获取到当前节点的第一个子节点
//通过以下方式就可以获取到文本内容所对应的节点
var textNode = Nodes[0].firstChild;
//对于文本节点来说,可以通过nodeValue的方式返回文本节点的文本内容
var responseMessage = textNode.nodeValue;
//将数据显示在页面上
//通过dom的方式找到div标签对应的元素节点
var spanNod = document.getElementById("result");
spanNod.innerHTML = responseMessage;
} else {
alert("xml数据错误" + xmlhttp.responseText);
}
} else {
alert("解析对象失败");
}
}
}
}
“GET”和“POST”的一个重要区别在于,“GET”方式传递给服务器的信息一般以后缀参数方式存在于URL地址中,而URL的长度通常都有限制,这也就限制了“GET”方式传递给服务器的内容大小
而“POST”方式传递给服务器的信息并不位于URL地址中,所以没有大小限制。
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)));
之前我们曾经说过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", //http请求方式
url:"AjaxServletDemo2", //服务器端url地址
data:"username="+username, //发送给服务器端的数据
dataType:"xml", //告诉jquery数据返回形式
success:callback //定义交互完成。回调函数的名字
})
}
function callback(data){
//需要将dom对象转换成jquery对象
var jqueryObj = $(data);
//获取message节点
var message = jqueryObj.children();
//获取文本内容
var text = message.text();
var resultObj = $("#result");
resultObj.html(text);
}
5、浏览器缓存问题
IE:若url地址未变,则读取缓存信息。
function verify() {
//解决中文乱麻问题的方法1,页面端发出的数据作一次encodeURI,服务器段使用new String(old.getBytes("iso8859-1"),"UTF-8");
//解决中文乱麻问题的方法2,页面端发出的数据作两次encodeURI,服务器段使用URLDecoder.decode(old,"UTF-8")
var url = "AJAXServer?name=" + encodeURI(encodeURI($("#userName").val()));
url = convertURL(url);
$.get(url,null,function(data){
$("#result").html(data);
});
}
//给url地址增加时间戳,骗过浏览器,不读取缓存
function convertURL(url) {
//获取时间戳
var timstamp = (new Date()).valueOf();
//将时间戳信息拼接到url上
//url = "AJAXServer"
if (url.indexOf("?") >= 0) {
url = url + "&t=" + timstamp;
} else {
url = url + "?t=" + timstamp;
}
return url;
}
IE:访问跨域页面时会给出提示,用户确认后会访问
Mozilla FireFox及其他:不允许访问跨域页面
[java] view plain copy
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://www.sohu.com/index.html?name=123&id=000
Proxy?url=http://www.sohu.com/index.html&name=123&id=000
url=http://www.sohu.com/index.html&name=123&id=000
http://www.sohu.com/index.html?id=000&name=123
}
}
由于对本来请求的地址和其包含的参数进行了转换,导致url参数中只包含原来请求的地址信息,而原来请求的参数信息则需要我们解析出来和地址信息一起重新组成本来的请求URL,因此方法开头的一段while就做了这个工作。
在从远端服务器读取数据时,要显示的指定输入流的编码格式,这样才可以保证通过BufferReader读到的内容不会有乱码信息