摘要:性能會有所降低一點內容,刷新整個頁面用戶的操作頁面會中斷整個頁面被刷新了就是能夠做到局部刷新三對象是中最重要的一個對象。頭信息已經接收,響應數據尚未接收。
一、什么是Ajax
Ajax(Asynchronous JavaScript and XML) 異步JavaScript和XML
Ajax實際上是下面這幾種技術的融合:
(1)XHTML和CSS的基于標準的表示技術
(2)DOM進行動態顯示和交互
(3)XML和XSLT進行數據交換和處理
(4)XMLHttpRequest進行異步數據檢索
(5)Javascript將以上技術融合在一起
客戶端與服務器,可以在【不必刷新整個瀏覽器】的情況下,與服務器進行異步通訊的技術
二、為什么我們需要Ajax?在我們之前的開發,每當用戶向服務器發送請求,哪怕只是需要更新一點點的局部內容,服務器都會將整個頁面進行刷新。
性能會有所降低(一點內容,刷新整個頁面!)
用戶的操作頁面會中斷(整個頁面被刷新了)
Ajax就是能夠做到局部刷新!
三、XMLHttpRequestXMLHttpRequest對象是Ajax中最重要的一個對象。使用Ajax更多的是編寫客戶端代碼,而不是服務端的代碼。
3.1XMLHttpRequest 工作原理傳統的web前端與后端的交互中,瀏覽器直接訪問Tomcat的Servlet來獲取數據。Servlet通過轉發把數據發送給瀏覽器。
當我們使用AJAX之后,瀏覽器是先把請求發送到XMLHttpRequest異步對象之中,異步對象對請求進行封裝,然后再與發送給服務器。服務器并不是以轉發的方式響應,而是以流的方式把數據返回給瀏覽器
XMLHttpRequest異步對象會不停監聽服務器狀態的變化,得到服務器返回的數據,就寫到瀏覽器上【因為不是轉發的方式,所以是無刷新就能夠獲取服務器端的數據】
3.2創建XMLHttpRequest對象要創建XMLHttpRequest對象是要分兩種情況考慮的:
在IE6以下的版本
在IE6以上的版本以及其他內核的瀏覽器(Mozilla)等
3.3了解XMLHttpRequest對象的屬性和方法 3.3.1方法
open()(String method,String url,boolean asynch,String username,String password)
send(content)
setRequestHeader(String header,String value)
getAllResponseHeaders()
getResponseHeader(String header)
abort()
常用的方法就是黑色粗體的前三個
open():該方法創建http請求
第一個參數是指定提交方式(post、get)
第二個參數是指定要提交的地址是哪
第三個參數是指定是異步還是同步(true表示異步,false表示同步)
第四和第五參數在http認證的時候會用到。是可選的
setRequestHeader(String header,String value):設置消息頭(使用post方式才會使用到,get方法并不需要調用該方法)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
send(content):發送請求給服務器
如果是get方式,并不需要填寫參數,或填寫null
如果是post方式,把要提交的參數寫上去
3.3.2屬性onreadystatechange:請求狀態改變的事件觸發器(readyState變化時會調用此方法),一般用于指定回調函數
readyState:請求狀態readyState一改變,回調函數被調用,它有5個狀態
0:未初始化
1:open方法成功調用以后
2:服務器已經應答客戶端的請求
3:交互中。Http頭信息已經接收,響應數據尚未接收。
4:完成。數據接收完成
responseText:服務器返回的文本內容
responseXML:服務器返回的兼容DOM的XML內容
status:服務器返回的狀態碼
statusText:服務器返回狀態碼的文本信息
上面有兩個地方都提及了回調函數,回調函數是什么??
回調函數就是接收服務器返回的內容!
四、編寫第一個Ajax程序檢測用戶輸入的用戶名是否為"zhongfucheng",只要不是zhongfucheng,就可以使用!
4.1html代碼創建的div只要用于顯示服務器返回的數據
當用戶點擊按鈕的時候,就觸發事件。
4.2JavaScript代碼
創建XMLHttpRequest對象
創建http請求
把文本框的數據發送給http請求的目標
指定回調函數
編寫回調函數
發送http請求
回調函數得到http返回的內容,把內容寫在div上
4.3效果
實現了局部更新,不需要刷新整一個頁面
五、XMLHttpRequest解決中文亂碼在傳統的Web中我們已經解決過中文亂碼問題了。
服務器傳送給瀏覽器數據發生亂碼:response設置編碼的時候和瀏覽器頁面的編碼一致便可以解決
瀏覽器傳送給服務器數據發生亂碼:如果是post方式,request設置編碼便可以解決。如果是get方式,Tomcat下,使用ISO8859-1編碼得到原本的二進制數組,再使用UTF-8編碼便可以解決
接下來,要介紹的是:我們可以屏蔽任何瀏覽器和任何服務器的編碼格式,瀏覽器發送給服務器的數據不造成亂碼問題!
具體我們是這樣做的:
發送數據給服務器的時候,JavaScript使用兩次EncodeURI()
服務器得到數據,使用URLEncode.decode(數據,"utf-8")進行解碼
為啥我能說這種方式屏蔽任何瀏覽器和服務器的編碼格式,都不會亂碼呢??
六、XMLHttpRequest解決緩存問題在傳統的Web中我們也解決過緩存的問題,通過設置response的頭信息,返回給瀏覽器就可以實現不緩存頁面了。
但是呢,現在我們使用XMLHttpRequest,拿到的不是全新的頁面,僅僅是服務器端發送過來的數據!!
那我們要怎么解決緩存的問題呢??產生緩存的原因就是:我們請求了同一個地址,做了相同的操作。服務端認為我的操作并沒有什么變化,就直接把緩存的信息給我了。這樣的話,我就不能更換驗證碼圖片了(等等應用)。
我們可以這樣做:
在每次請求url中加入一個時間戳參數【每次url就不一樣了】
加入時間戳參數到url時,也分兩種情況
url本身就帶有參數了,也就是說有"?"號了,那么添加時間戳的時候就需要用"&"號
[x] url沒有參數,直接使用"?"號來添加時間戳
if(url.indexOf("?") >= 0){ url = url + "&t=" + (new Date()).valueOf(); } else{ url = url + "?t=" + (new Date()).valueOf(); }七、XMLHttpRequest跨域訪問
使用XMLHttpRequest去跨域訪問是會出現錯誤的。
我們要怎么解決呢??這時候就要用代理思想了
XMLHttpRequest先把請求提交給同域的Servlet處理
同域Servlet再將XMLHttpRequest的請求提交給跨域的服務器
同域Servlet得到跨域服務器的返回值,再返回給XMLHttpRequest
這個時候,XMLHttpRequest跨域訪問就分兩種(GET和POST)情況了,因為這兩種提交數據的方式是不一樣的!
7.1瀏覽器代碼我們需要在調用open方法之前判斷一下要連接的地址是不是以http開頭的,如果是則認為要訪問的是跨域的資源
首先將當前url中的”?”變成”&”,這是因為將要連接的地址改為”Proxy?url=” + url以后,如果原來url地址中有參數的話,新的url地址中就會有兩個“?”這會導致服務器端解析參數錯誤,”url=”之后的內容表示本來要訪問的跨域資源的地址。
7.2GET方式GET方式是直接把參數的信息都放在url地址上,所以處理起來會相對簡單。
步驟:
使用StringBuilder裝載著getParameter("url")【獲取得到地址,呆會要做拼接,所以用StringBuilder】
得到其他參數的時候,做URLEncode.encode(),因為我們進入Servlet的時候已經被decode了一次【我們要盡可能保留原始請求】(參照解決中文亂碼)
遍歷所有的請求參數,只要名字不是"url",就添加到StringBuilder中【第一個參數為"?",其他的參數為"&"】(http://localhost:8080/url?aa=bb&cc=dd)
創建URL對象,把拼接成的StringBuilder傳遞進去
使用BufferReader讀取遠程服務器返回的數據,要指定輸入流編碼格式,否則會亂碼
BufferedReader reader = new BufferedReader(new InputStreamReader(URL對象.openSteam(),"UTF-8"));
最后,把遠程服務器讀取到的數據再返回給XMLHttpRequest
7.3POST方式POST方式把參數的信息都封裝到HTTP請求中,在URL進行連接的時候,需要把數據寫給遠程服務器
步驟:
得到url參數,創建StringBuilder
得到其他參數的時候,做URLEncode.encode(),因為我們進入Servlet的時候已經被decode了一次【我們要盡可能保留原始請求】(參照解決中文亂碼)
遍歷所有的請求參數,只要名字不是"url",就添加到StringBuilder中【第一個參數直接給出,其他的參數為"&"】(aa=bb&cc=dd&ee=ff)
創建URL對象,創建URL連接器,允許寫數據到遠程服務器上
URL url = new URL(url); URLConnection connection = url.openConnection; connection.setDoOutPut(true);
得到寫數據流
OutputSteamWriter writer = new OutputSteamWriter(conncetion.getOutputSteam)
把StringBuilder的數據寫到遠程服務器上,并flush
使用BufferReader讀取遠程服務器返回的數據
BufferedReader reader = new BufferedReader(new InputSteamReader(conncetion.inputSteamReader,"UTF-8"));八、AJAX二級下拉聯動案例【XML版】
我們在購物的時候,常常需要我們來選擇自己的收貨地址,先選擇省份,再選擇城市...
有沒有發現:當我們選擇完省份的時候,出現的城市全部都是根據省份來給我們選擇的。這是怎么做到的呢???其實就是通過AJAX來完成的。使用AJAX技術讓我們看起來網頁非常“智能”,會根據省份來給出對應的城市信息。
我們這里就不讀取數據庫了,直接在Servlet寫死數據來進行模擬測試。
8.1分析我們知道AJAX與服務器之間的交互常用的傳輸載體格式有三種:
HTML
XML
JSON
由于省份與城市是有層級關系的,因此我們只能用XML或者JSON。
我們這里首先就用XML來進行,后面會使用JSON,來看看他倆有什么不同的地方。。
8.1.1前臺分析當用戶選擇了某個省份之后,就使用AJAX與服務器進行交互,那么在選擇城市的時候就出現對應的城市信息。
監聽下拉框值變化事件
只要下拉框值變化了,就與服務器進行交互
得到服務器返回的值,解析XML
使用DOM把數據寫到城市下拉框列表中
8.1.2后臺分析得到前臺帶過來的數據
判斷該數據是什么,返回對應的的XML文件
8.2寫JSP頁面<%-- Created by IntelliJ IDEA. User: ozc Date: 2017/5/17 Time: 19:38 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %>8.3Servlet多級聯動 <%--############前臺頁面###################--%> <%--############AJAX###################--%>
import java.io.IOException; import java.io.PrintWriter; /** * Created by ozc on 2017/5/17. */ @javax.servlet.annotation.WebServlet(name = "ProvinceServlet",urlPatterns = "/ProvinceServlet") public class ProvinceServlet extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { //設置中文編碼 request.setCharacterEncoding("UTF-8"); String province = request.getParameter("province"); //這里是返回的是XML,因此指定XML數據! response.setContentType("text/xml;charset=UTF-8"); PrintWriter printWriter = response.getWriter(); /****************返回XML文件給前臺**************/ printWriter.write(""); printWriter.write("8.4效果: 8.5XML方式總結"); if("廣東".equals(province)){ printWriter.write(" "); System.out.println("1111"); /*******事后操作*******/ printWriter.flush(); printWriter.close(); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { this.doPost(request, response); } }廣州 "); printWriter.write("深圳 "); printWriter.write("中山 "); }else if("湖南".equals(province)){ printWriter.write("長沙 "); printWriter.write("株洲 "); printWriter.write("湘潭 "); printWriter.write("岳陽 "); } printWriter.write("
監聽下拉框的變化,如果變化了,那么就使用異步操作去訪問服務器,得到對應的數據返回給異步對象
異步對象解析服務器帶過來的數據,使用DOM編程把數據動態添加到頁面上
在Servlet上記得要指定返回的是XML的數據!
在前臺解析XML文檔的時候,不能直接使用innerHtml來得到節點的值,只能通過firstChild.nodeValue的方式獲取。
由于每次append到下拉框都會連續append,因此在響應事件的時候,把下拉框清零
把下拉框options的長度賦值為1,那么就是清零的操作了。
九、AJAX二級下拉聯動案例【JSON版】前面我們已經使用過了XML作為數據載體在AJAX中與服務器進行交互。當時候我們的案例是二級聯動,使用Servlet進行控制
這次我們使用JSON作為數據載體在AJAX與服務器交互,使用三級聯動,使用Action進行控制....
省份-城市-區域三級聯動【Struts2 + JSON版】
9.1分析與上次是一樣的,只不過這次換了用JSON,使用Action控制罷了...
監聽下拉框的變動,使用異步對象與服務器進行交互。
9.1.1前臺分析監聽下拉框的變動
得到服務器返回的JSON數據
使用eval()進行解析,得到具體的對象
使用DOM編程把數據填充到對應的下拉框上
9.1.2后臺分析得到前臺發送過來的數據
判斷具體的數據是什么,給出對應的數據
使用Struts2提供的組件把數據封裝成JSON
返回給瀏覽器
9.2監聽省份JSP頁面<%-- Created by IntelliJ IDEA. User: ozc Date: 2017/5/18 Time: 13:36 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %>9.3監聽省份Action使用JSON數據載體與服務器進行交互 <%--############前臺頁面##############################--%> <%--############監聽省份##############################--%>
要想Struts2能夠把Action的數據封裝成JSON,就需要導入Struts2的開發包
struts2-json-plugin-2.3.4.1.jar
在Action中對應的成員屬性需要給getter方法
import com.opensymphony.xwork2.ActionSupport; import java.util.ArrayList; import java.util.List; /** * Created by ozc on 2017/5/18. */ public class ProvinceAction extends ActionSupport{ //自動封裝數據 private Bean bean; public Bean getBean() { return bean; } public void setBean(Bean bean) { this.bean = bean; } //封裝城市的集合 private Listcity = new ArrayList<>(); public List getCity() { return city; } public String findCityByProvince() throws Exception { if ("廣東".equals(bean.getName())) { city.add("廣州"); city.add("珠海"); city.add("從化"); } else if ("北京".equals(bean.getName())) { city.add("一環"); city.add("二環"); city.add("三環"); city.add("四環"); } else { System.out.println("沒有你選擇的地區"); } return "ok"; } }
返回給前端的時候,數據是這樣子的:
9.4效果 9.5監聽城市JSP<%--############監聽城市##############################--%>9.6Action頁面
public String findAreaByCity() throws Exception { if ("廣州".equals(bean.getName())) { area.add("白云區"); area.add("黃浦區"); area.add("蘿崗區"); } else if ("珠海".equals(bean.getName())) { area.add("香江"); area.add("拱北"); area.add("EE"); area.add("xx"); } else { System.out.println("沒有你選擇的地區"); } return "ok"; }9.7最終效果: 9.8總結
這次使用的是JSON作為數據載體與服務器進行交互,和XML本質上是沒有區別的。
只不過JSON是更加輕量級文本數據,在JavaScript能夠方便地獲取返回的數據
在Struts2中把Action數據封裝成JSON格式,返回給異步對象
需要導入jar包
在配置文件中配置繼承json包
返回的類型是json
如果使用POST時,發送的key、vaulue太多的話,我們可以使用bean進行封裝
當選中省份時,把城市和區域的下拉框清空,當選擇城市時,把區域的下拉框清空
十、總結圖如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章的同學,可以關注微信公眾號:Java3y
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/76323.html
摘要:前言由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 前言 由于寫的文章已經是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導航哦~想要獲取最新原創的技術文章歡迎關注我的公眾號:Java3y Java3y文章目錄導航 Java基礎 泛型就這么簡單 注解就這么簡單 Druid數據庫連接池...
摘要:前言上一次我們對的應用進行了一次全面的分析,這一次我們來聊聊。 showImg(https://segmentfault.com/img/remote/1460000020077803?w=1280&h=853); 前言 上一次我們對Paging的應用進行了一次全面的分析,這一次我們來聊聊WorkManager。 如果你對Paging還未了解,推薦閱讀這篇文章: Paging在Recy...
摘要:目錄前言架構安裝第一個爬蟲爬取有道翻譯創建項目創建創建解析運行爬蟲爬取單詞釋義下載單詞語音文件前言學習有一段時間了,當時想要獲取一下百度漢字的解析,又不想一個個漢字去搜,復制粘貼太費勁,考慮到爬蟲的便利性,這篇文章是介紹一個爬蟲框架, 目錄 前言 架構 安裝 第一個爬蟲:爬取有道翻譯 創建項目 創建Item 創建Spider 解析 運行爬蟲-爬取單詞釋義 下載單詞語音文件 ...
摘要:采用完全獨立于任何程序語言的文本格式,使成為理想的數據交換語言為什么需要提到,我們就應該和來進行對比。也是一種存儲和交換文本信息的手段。那么好在哪里呢比更小更快,更易解析。使用的時候,也支持將轉成但是,我們不一定使用框架來做開發呀。 什么是JSON JSON:JavaScript Object Notation 【JavaScript 對象表示法】 JSON 是存儲和交換文本信息的語法...
摘要:要是使用到日歷的話,我們想到使用這個日歷類上面僅僅是我個人總結的要點,如果有錯誤的地方還請大家給我指正。 納稅服務系統總結 納稅服務系統是我第一個做得比較大的項目(不同于javaWeb小項目),該項目系統來源于傳智Java32期,十天的視頻課程(想要視頻的同學關注我的公眾號就可以直接獲取了) 我跟著練習一步一步完成需求,才發覺原來Java是這樣用來做網站的,Java有那么多的類庫,頁面...
閱讀 1970·2021-11-22 15:33
閱讀 3006·2021-11-18 10:02
閱讀 2614·2021-11-08 13:16
閱讀 1628·2021-10-09 09:57
閱讀 1375·2021-09-30 09:47
閱讀 2009·2019-08-29 13:05
閱讀 3073·2019-08-29 12:46
閱讀 1013·2019-08-29 12:19