AJAX(Asynchronous Javascript And Xml)
傳統請求及缺點
- 傳統的請求都有哪些?
- 直接在浏覽器位址欄上輸入URL。
- 點選超連結
- 送出form表單
- 使用JS代碼發送請求
- window.open(url)
- document.location.href = url
- window.location.href = url
- ....
- 傳統請求存在的問題
- 頁面全部重新整理導緻了使用者的體驗較差。
- 傳統的請求導緻使用者的體驗有空白期。(使用者的體驗是不連貫的)
AJAX概述
- AJAX不能稱為一種技術,它是多種技術的綜合産物。
- AJAX可以讓浏覽器發送一種特殊的請求,這種請求可以是:異步的。
- 什麼是異步,什麼是同步?
- 假設有t1和t2線程,t1和t2線程并發,就是異步。
- 假設有t1和t2線程,t2在執行的時候,必須等待t1線程執行到某個位置之後t2才能執行,那麼t2在等t1,顯然他們是排隊的,排隊的就是同步。
- AJAX是可以發送異步請求的。也就是說,在同一個浏覽器頁面當中,可以發送多個ajax請求,這些ajax請求之間不需要等待,是并發的。
- AJAX代碼屬于WEB前端的JS代碼。和後端的java沒有關系,後端也可以是php語言,也可以是C語言。
- AJAX 應用程式可能使用 XML 來傳輸資料,但将資料作為純文字或 JSON 文本傳輸也同樣常見。
- AJAX可以更新網頁的部分,而不需要重新加載整個頁面。(頁面局部重新整理)
- AJAX可以做到在同一個網頁中同時啟動多個請求,類似于在同一個網頁中啟動“多線程”,一個“線程”一個“請求”。
-
AjaxAJAX(Asynchronous Javascript And Xml) -
AjaxAJAX(Asynchronous Javascript And Xml)
XMLHttpRequest對象
- XMLHttpRequest對象是AJAX的核心對象,發送請求以及接收伺服器資料的傳回,全靠它了。
- XMLHttpRequest對象,現代浏覽器都是支援的,都内置了該對象。直接用即可。
- 建立XMLHttpRequest對象
-
var xhr = new XMLHttpRequest();
-
- XMLHttpRequest對象的方法
方法 | 描述 |
---|---|
abort() | 取消目前請求 |
getAllResponseHeaders() | 傳回頭部資訊 |
getResponseHeader() | 傳回特定的頭部資訊 |
open(method, url, async, user, psw) | 規定請求method:請求類型 GET 或 POSTurl:檔案位置async:true(異步)或 false(同步)user:可選的使用者名稱psw:可選的密碼 |
send() | 将請求發送到伺服器,用于 GET 請求 |
send(string) | 将請求發送到伺服器,用于 POST 請求 |
setRequestHeader() | 向要發送的報頭添加标簽/值對 |
- XMLHttpRequest對象的屬性
屬性 | 描述 |
---|---|
onreadystatechange | 定義當 readyState 屬性發生變化時被調用的函數 |
readyState | 儲存 XMLHttpRequest 的狀态。0:請求未初始化 1:伺服器連接配接已建立 2:請求已收到 3:正在處理請求 4:請求已完成且響應已就緒 |
responseText | 以字元串傳回響應資料 |
responseXML | 以 XML 資料傳回響應資料 |
status | 傳回請求的狀态号200: "OK"403: "Forbidden"404: "Not Found" |
statusText | 傳回狀态文本(比如 "OK" 或 "Not Found") |
AJAX GET請求
- 發送AJAX get請求,前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>發送ajax get請求</title> </head> <body> <script type="text/javascript"> window.onload = function () { document.getElementById("btn").onclick = function () { //1. 建立AJAX核心對象 var xhr = new XMLHttpRequest(); //2. 注冊回調函數 xhr.onreadystatechange = function(){ if (this.readyState == 4) { if (this.status == 200) { // 通過XMLHttpRequest對象的responseText屬性可以擷取到伺服器響應回來的内容。 // 并且不管伺服器響應回來的是什麼,都以普通文本的形勢擷取。(伺服器可能響應回來:普通文本、XML、JSON、HTML...) // innerHTML屬性是javascript中的文法,和ajax的XMLHttpRequest對象無關。 // innerHTML可以設定元素内部的HTML代碼。(innerHTML可以将後面的内容當做一段HTML代碼解釋并執行) //document.getElementById("myspan").innerHTML = this.responseText document.getElementById("mydiv").innerHTML = this.responseText // innerText也不是AJAX中的,是javascript中的元素屬性,和XMLHttpRequest無關。 // innerText也是設定元素中的内容,但是即使後面是一段HTML代碼,也是将其看做一個普通字元串設定進去。 //document.getElementById("myspan").innerText = this.responseText }else{ alert(this.status) } } } //3. 開啟通道 xhr.open("GET", "/ajax/ajaxrequest2", true) //4. 發送請求 xhr.send() } } </script> <button id="btn">發送ajax get請求</button> <span id="myspan"></span> <div id="mydiv"></div> </body> </html>
- 發送AJAX get請求,後端代碼:
package com.bjpowernode.ajax.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @program: 代碼 * @ClassName: AjaxRequest2Servlet * @version: 1.0 * @description: * @author: bjpowernode * @create: 2022-05-13 10:46 **/ @WebServlet("/ajaxrequest2") public class AjaxRequest2Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 設定響應的内容類型以及字元集 response.setContentType("text/html;charset=UTF-8"); // 擷取響應流 PrintWriter out = response.getWriter(); // 響應 out.print("<font color='red'>使用者名已存在!!!</font>"); } }
- AJAX get請求如何送出資料呢?
- get請求送出資料是在“請求行”上送出,格式是:url?name=value&name=value&name=value....
- 其實這個get請求送出資料的格式是HTTP協定中規定的,遵循協定即可。
AJAX GET請求的緩存問題
- 對于低版本的IE浏覽器來說,AJAX的get請求可能會走緩存。存在緩存問題。對于現代的浏覽器來說,大部分浏覽器都已經不存在AJAX get緩存問題了。
- 什麼是AJAX GET請求緩存問題呢?
- 在HTTP協定中是這樣規定get請求的:get請求會被緩存起來。
- 發送AJAX GET請求時,在同一個浏覽器上,前後發送的AJAX請求路徑一樣的話,對于低版本的IE來說,第二次的AJAX GET請求會走緩存,不走伺服器。
- POST請求在HTTP協定中規定的是:POST請求不會被浏覽器緩存。
- GET請求緩存的優缺點:
- 優點:直接從浏覽器緩存中擷取資源,不需要從伺服器上重新加載資源,速度較快,使用者體驗好。
- 缺點:無法實時擷取最新的伺服器資源。
- 浏覽器什麼時候會走緩存?
- 第一:是一個GET請求
- 第二:請求路徑已經被浏覽器緩存過了。第二次發送請求的時候,這個路徑沒有變化,會走浏覽器緩存。
- 如果是低版本的IE浏覽器,怎麼解決AJAX GET請求的緩存問題呢?
- 可以在請求路徑url後面添加一個時間戳,這個時間戳是随時變化的。是以每一次發送的請求路徑都是不一樣的,這樣就不會走浏覽器的緩存問題了。
- 可以采用時間戳:"url?t=" + new Date().getTime()
- 或者可以通過随機數:"url?t=" + Math.random()
- 也可以随機數+時間戳....
AJAX POST請求
- AJAX POST請求和GET請求的代碼差別在哪裡?就是前端代碼有差別。後端代碼沒有差別。
// 4. 發送AJAX POST請求 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") // 設定請求頭的内容類型。模拟form表單送出資料。 // 擷取表單中的資料 var username = document.getElementById("username").value; var password = document.getElementById("password").value; // send函數中的參數就是發送的資料,這個資料在“請求體”當中發送。 xhr.send("username="+username+"&password="+password)
- 實作一個案例:使用AJAX POST請求實作使用者注冊的時候,使用者名是否可用。(驗證使用者名是否可以注冊)實作步驟如下:
- 在前端,使用者輸入使用者名之後,失去焦點事件blur發生,然後發送AJAX POST請求,送出使用者名
- 在後端,接收到使用者名,連接配接資料庫,根據使用者名去表中搜尋
- 如果使用者名已存在
- 後端響應消息:對不起,使用者名已存在(在前端頁面以紅色字型展示)
- 如果使用者名不存在
- 後端響應消息:使用者名可以使用(在前端頁面以綠色字型展示)
- 實作一個案例:使用者點選按鈕之後,發送AJAX請求,顯示學生清單。
- 在後端java程式中拼接HTML代碼,然後将HTML代碼直接響應到浏覽器用戶端。這種方式不好,不應該在java代碼中編寫HTML代碼,能否在java程式中直接向前端響應資料?可以,可以在後端拼接JSON格式的字元串,或者XML格式的字元串,将這個字元串發送給前端,前端解析即可。
基于JSON的資料交換
- 在WEB前端中,如何将一個json格式的字元串轉換成json對象
var jsonStr = "{\"username\" : \"zhangsan\", \"password\" : \"1233344\"}" var jsonObj = JSON.parse(jsonStr) console.log(jsonObj.username) console.log(jsonObj.password)
- 在後端拼接JSON格式的字元串,響應給前端的浏覽器
json.append("["); while (rs.next()) { // 擷取每個學生的資訊 String name = rs.getString("name"); String age = rs.getString("age"); String addr = rs.getString("addr"); // 拼接json格式的字元串 // {"name":" 王五 ","age": 20 ,"addr":" 北京大興區 "}, json.append("{\"name\":\""); json.append(name); json.append("\",\"age\":"); json.append(age); json.append(",\"addr\":\""); json.append(addr); json.append("\"},"); } jsonStr = json.substring(0, json.length() - 1) + "]";
- 拼接JSON格式的字元串太痛苦,可以使用阿裡巴巴的fastjson元件,它可以将java對象轉換成json格式的字元串
注意:使用fastjson需要引入fastjson-1.2.2.jarList<Student> studentList = new ArrayList<>(); while (rs.next()) { // 取出資料 String name = rs.getString("name"); int age = rs.getInt("age"); String addr = rs.getString("addr"); // 将以上資料封裝成Student對象 Student s = new Student(name, age, addr); // 将Student對象放到List集合 studentList.add(s); } // 将List集合轉換成json字元串 jsonStr = JSON.toJSONString(studentList);
基于XML的資料交換
- 注意:如果伺服器端響應XML的話,響應的内容類型需要寫成:
response.setContentType("text/xml;charset=UTF-8");
- xml和JSON都是常用的資料交換格式
- XML體積大,解析麻煩。較少用。
- JSON體積小,解析簡單,較常用。
- 基于XML的資料交換,前端代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用XML完成資料交換</title> </head> <body> <script type="text/javascript"> window.onload = function(){ document.getElementById("btn").onclick = function(){ // 1.建立XMLHTTPRequest對象 var xhr = new XMLHttpRequest(); // 2.注冊回調函數 xhr.onreadystatechange = function () { if (this.readyState == 4) { if (this.status == 200) { // 伺服器端響應了一個XML字元串,這裡怎麼接收呢? // 使用XMLHTTPRequest對象的responseXML屬性,接收傳回之後,可以自動封裝成document對象(文檔對象) var xmlDoc = this.responseXML //console.log(xmlDoc) // 擷取所有的<student>元素,傳回了多個對象,應該是數組。 var students = xmlDoc.getElementsByTagName("student") //console.log(students[0].nodeName) var html = ""; for (var i = 0; i < students.length; i++) { var student = students[i] // 擷取<student>元素下的所有子元素 html += "<tr>" html += "<td>"+(i+1)+"</td>" var nameOrAge = student.childNodes for (var j = 0; j < nameOrAge.length; j++) { var node = nameOrAge[j] if (node.nodeName == "name") { //console.log("name = " + node.textContent) html += "<td>"+node.textContent+"</td>" } if (node.nodeName == "age") { //console.log("age = " + node.textContent) html += "<td>"+node.textContent+"</td>" } } html += "</tr>" } document.getElementById("stutbody").innerHTML = html }else{ alert(this.status) } } } // 3.開啟通道 xhr.open("GET", "/ajax/ajaxrequest6?t=" + new Date().getTime(), true) // 4.發送請求 xhr.send() } } </script> <button id="btn">顯示學生清單</button> <table width="500px" border="1px"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>年齡</th> </tr> </thead> <tbody id="stutbody"> <!--<tr> <td>1</td> <td>zhangsan</td> <td>20</td> </tr> <tr> <td>2</td> <td>lisi</td> <td>22</td> </tr>--> </tbody> </table> </body> </html>
- 基于XML的資料交換,後端java程式:
package com.bjpowernode.ajax.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @program: 代碼 * @ClassName: AjaxRequest6Servlet * @version: 1.0 * @description: 伺服器端傳回XML字元串 * @author: bjpowernode * @create: 2022-05-15 11:48 **/ @WebServlet("/ajaxrequest6") public class AjaxRequest6Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 注意:響應的内容類型是XML。 response.setContentType("text/xml;charset=UTF-8"); PrintWriter out = response.getWriter(); /* <students> <student> <name>zhangsan</name> <age>20</age> </student> <student> <name>lisi</name> <age>22</age> </student> </students> */ StringBuilder xml = new StringBuilder(); xml.append("<students>"); xml.append("<student>"); xml.append("<name>zhangsan</name>"); xml.append("<age>20</age>"); xml.append("</student>"); xml.append("<student>"); xml.append("<name>lisi</name>"); xml.append("<age>22</age>"); xml.append("</student>"); xml.append("</students>"); out.print(xml); } }
AJAX亂碼問題
- 測試内容:
- 發送ajax get請求
- 發送資料到伺服器,伺服器擷取的資料是否亂碼?
- 伺服器響應給前端的中文,會不會亂碼?
- 發送ajax post請求
- 發送資料到伺服器,伺服器擷取的資料是否亂碼?
- 伺服器響應給前端的中文,會不會亂碼?
- 發送ajax get請求
- 包括還要測試tomcat伺服器的版本:
- tomcat10和tomcat9都要進行測試。
- 測試結果:
- 對于tomcat10來說,關于字元集,我們程式員不需要幹涉,不會出現亂碼。
- 對于tomcat9來說呢?
- 響應中文的時候,會出現亂碼,怎麼解決?
response.setContentType("text/html;charset=UTF-8");
- 發送ajax post請求的時候,發送給伺服器的資料,伺服器接收之後亂碼,怎麼解決?
request.setCharacterEncoding("UTF-8");
- 響應中文的時候,會出現亂碼,怎麼解決?
AJAX的異步與同步
- 什麼是異步?什麼是同步?
- ajax請求1和ajax請求2,同時并發,誰也不用等誰,這就是異步。(a不等b,b也不等a)
- 如果ajax請求1在發送的時候需要等待ajax請求2結束之後才能發送,那麼這就是同步。(a等待b,或者b等待a,隻要發生等待,就是同步。)
- 異步和同步在代碼上如何實作?
// 假設這個是ajax請求1 // 如果第三個參數是false:這個就表示“ajax請求1”不支援異步,也就是說ajax請求1發送之後,會影響其他ajax請求的發送,隻有當我這個請求結束之後,你們其他的ajax請求才能發送。 // false表示,不支援異步。我這個請求發了之後,你們其他的請求都要靠邊站。都等着。你們别動呢,等我結束了你們再說。 xhr1.open("請求方式", "URL", false) xhr1.send() // 假設這個是ajax請求2 // 如果第三個參數是true:這個就表示“ajax請求2”支援異步請求,也就是說ajax請求2發送之後,不影響其他ajax請求的發送。 xhr2.open("請求方式", "URL", true) xhr2.send()
- 什麼情況下用同步?(大部分情況下我們都是使用ajax異步方式,同步很少用。)
- 舉一個例子
- 使用者注冊
- 使用者名需要發送ajax請求進行校驗
- 郵箱位址也需要發送ajax請求校驗
- 其他的也可能需要發送ajax請求。。。
- 并且最終注冊按鈕的時候,也是發送ajax請求進行注冊。
- 那麼顯然,注冊的Ajax請求和校驗的ajax請求不能異步,必須等待所有的校驗ajax請求結束之後,注冊的ajax請求才能發。
- 使用者注冊
- 舉一個例子
AJAX代碼封裝
- AJAX請求相關的代碼都是類似的,有很多重複的代碼,這些重複的代碼能不能不寫,能不能封裝一個工具類。要發送ajax請求的話,就直接調用這個工具類中的相關函數即可。
- 接下來,手動封裝一個工具類,這個工具類我們可以把它看做是一個JS的庫。我們把這個JS庫起一個名字,叫做jQuery。(我這裡封裝的jQuery隻是一個前端的庫,和後端的java沒有關系,隻是為了友善web前端代碼的編寫,提高WEB前端的開發效率)
- 手動開發jQuery,源代碼
function jQuery(selector){ if (typeof selector == "string") { if (selector.charAt(0) == "#") { domObj = document.getElementById(selector.substring(1)) return new jQuery() } } if (typeof selector == "function") { window.onload = selector } this.html = function(htmlStr){ domObj.innerHTML = htmlStr } this.click = function(fun){ domObj.onclick = fun } this.focus = function (fun){ domObj.onfocus = fun } this.blur = function(fun) { domObj.onblur = fun } this.change = function (fun){ domObj.onchange = fun } this.val = function(v){ if (v == undefined) { return domObj.value }else{ domObj.value = v } } // 靜态的方法,發送ajax請求 /** * 分析:使用ajax函數發送ajax請求的時候,需要程式員給我們傳過來什麼? * 請求的方式(type):GET/POST * 請求的URL(url):url * 請求時送出的資料(data):data * 請求時發送異步請求還是同步請求(async):true表示異步,false表示同步。 */ jQuery.ajax = function(jsonArgs){ // 1. var xhr = new XMLHttpRequest(); // 2. xhr.onreadystatechange = function(){ if (this.readyState == 4) { if (this.status == 200) { // 我們這個工具類在封裝的時候,先不考慮那麼多,假設伺服器傳回的都是json格式的字元串。 var jsonObj = JSON.parse(this.responseText) // 調用函數 jsonArgs.success(jsonObj) } } } if (jsonArgs.type.toUpperCase() == "POST") { // 3. xhr.open("POST", jsonArgs.url, jsonArgs.async) // 4. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") xhr.send(jsonArgs.data) } if (jsonArgs.type.toUpperCase() == "GET") { xhr.open("GET", jsonArgs.url + "?" + jsonArgs.data, jsonArgs.async) xhr.send() } } } $ = jQuery // 這裡有個細節,執行這個目的是為了讓靜态方法ajax生效。 new jQuery()
- 使用以上庫,怎麼用?
<script type="text/javascript" src="/ajax/js/jQuery-1.0.0.js"></script> <script type="text/javascript"> $(function(){ $("#btn1").click(function(){ $.ajax({ type : "POST", url : "/ajax/ajaxrequest11", data : "username=" + $("#username").val(), async : true, success : function(json){ $("#div1").html(json.uname) } }) }) }) </script>
AJAX實作省市關聯
- 什麼是省市關聯?
- 在網頁上,選擇對應的省份之後,動态的關聯出該省份對應的市。選擇對應的市之後,動态的關聯出該市對應的區。(首先要清楚需求)
- 進行資料庫表的設計
-
t_area (區域表) id(PK-自增) code name pcode --------------------------------------------- 1 001 河北省 null 2 002 河南省 null 3 003 石家莊 001 4 004 邯鄲 001 5 005 鄭州 002 6 006 洛陽 002 7 007 叢台區 004 将全國所有的省、市、區、縣等資訊都存儲到一張表當中。 采用的存儲方式實際上是code pcode形勢。
-
- 建表t_area,模拟好資料。
- 首先實作第一個功能:
- 頁面加載完畢之後,先把省份全部展現出來。
AJAX跨域問題
跨域
- 跨域是指從一個域名的網頁去請求另一個域名的資源。比如從百度(https://baidu.com)頁面去請求京東(https://www.jd.com)的資源。
- 通過超連結或者form表單送出或者window.location.href的方式進行跨域是不存在問題的(大家可以編寫程式測試一下)。但在一個域名的網頁中的一段js代碼發送ajax請求去通路另一個域名中的資源,由于同源政策的存在導緻無法跨域通路,那麼ajax就存在這種跨域問題。
- 同源政策是指一段腳本隻能讀取來自同一來源的視窗和文檔的屬性,同源就是協定、域名和端口都相同。
- 同源政策有什麼用?如果你剛剛在網銀輸入賬号密碼,檢視了自己還有1萬塊錢,緊接着通路一些不規矩的網站,這個網站可以通路剛剛的網銀站點,并且擷取賬号密碼,那後果可想而知。是以,從安全的角度來講,同源政策是有利于保護網站資訊的。
- 有一些情況下,我們是需要使用ajax進行跨域通路的。比如某公司的A頁面(a.bjpowernode.com)有可能需要擷取B頁面(b.bjpowernode.com)。
同源還是不同源
- 區分同源和不同源的三要素
-
- 協定
- 域名
- 端口
- 協定一緻,域名一緻,端口号一緻,三個要素都一緻,才是同源,其它一律都是不同源
URL1 | URL2 | 是否同源 | 描述 |
---|---|---|---|
http://localhost:8080/a/index.html | http://localhost:8080/a/first | 同源 | 協定 域名 端口一緻 |
http://localhost:8080/a/index.html | http://localhost:8080/b/first | 同源 | 協定 域名 端口一緻 |
http://www.myweb.com:8080/a.js | https://www.myweb.com:8080/b.js | 不同源 | 協定不同 |
http://www.myweb.com:8080/a.js | http://www.myweb.com:8081/b.js | 不同源 | 端口不同 |
http://www.myweb.com/a.js | http://www.myweb2.com/b.js | 不同源 | 域名不同 |
http://www.myweb.com/a.js | http://crm.myweb.com/b.js | 不同源 | 子域名不同 |
複現AJAX跨域問題
AJAX跨域解決方案
方案1:設定響應頭
- 核心原理:跨域通路的資源允許你跨域通路。
- 實作:
-
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 允許某個 response.setHeader("Access-Control-Allow-Origin", "*"); // 允許所有
-
方案2:jsonp
- jsonp:json with padding(帶填充的json【學完之後再了解這個什麼意思!!!】)
- jsonp不是一個真正的ajax請求。隻不過可以完成ajax的局部重新整理效果。可以說jsonp是一種類ajax請求的機制。
- jsonp不是ajax請求,但是可以完成局部重新整理的效果,并且可以解決跨域問題。
- 注意:jsonp解決跨域的時候,隻支援GET請求。不支援post請求。
方案3:jQuery封裝的jsonp
- 牛人們寫的jQuery庫,已經對jsonp進行了封裝。大家可以直接拿來用。
-
-
$.ajax({ type : "GET", url : "跨域的url", dataType : "jsonp", // 指定資料類型 jsonp : "fun", // 指定參數名(不設定的時候,預設是:"callback") jsonpCallback : "sayHello" // 指定回調函數的名字 // (不設定的時候,jQuery會自動生成一個随機的回調函數, //并且這個回調函數還會自動調用success的回調函數。) })
-
方案4:代理機制(httpclient)
- 使用Java程式怎麼去發送get/post請求呢?【GET和POST請求就是HTTP請求。】
- 第一種方案:使用JDK内置的API(java.net.URL.....),這些API是可以發送HTTP請求的。
- 第二種方案:使用第三方的開源元件,比如:apache的httpclient元件。(httpclient元件是開源免費的,可以直接用)
- 在java程式中,使用httpclient元件可以發送http請求。
- 對于httpclient元件的代碼,大家目前可以不進行深入的研究,可以從網上直接搜。然後粘貼過來,改一改,看看能不能完成發送get和post請求。
- 使用httpclient元件,需要先将這個元件相關的jar包引入到項目當中。
方案5:nginx反向代理
- nginx反向代理中也是使用了這種代理機制來完成AJAX的跨域,實作起來非常簡單,隻要修改一個nginx的配置即可。以後大家學習nginx之後再說吧。!!!!
AJAX實作搜尋聯想 自動補全
- 什麼是搜尋聯想?自動補全?
- 百度是一個很典型的代表。在百度的搜尋框中輸入相關資訊的時候,會有搜尋聯想以及自動補全。
- 搜尋聯想和自動補全:實際上是為了友善使用者的使用。讓使用者的體驗更好。
- 搜尋聯想:當使用者輸入一些單詞之後,自動聯想出使用者要搜尋的資訊,給一個提示。
- 自動補全:當聯想出一些内容之後,使用者點選某個聯想的單詞,然後将這個單詞自動補全到搜尋框當中。
- 搜尋聯想和自動補全功能,因為是頁面局部重新整理效果,是以需要使用ajax請求來完成。
- 搜尋聯想,自動補全功能的核心實作原理?
- 當鍵盤事件發生之後,比如:keyup:鍵彈起事件。
- 發送ajax請求,請求中送出使用者輸入的搜尋内容,例如:北京(發送ajax請求,攜帶“北京”兩個字)
- 後端接收到ajax請求,接收到“北京”兩個字,執行select語句進行模糊查詢。傳回查詢結果。
- 将查詢結果封裝成json格式的字元串,将json格式的字元串響應到前端。
- 前端接收到json格式的字元串之後,解析這個json字元串,動态展示頁面。
附錄:HTTP狀态資訊
1xx: 資訊
消息: | 描述: |
---|---|
100 Continue | 伺服器僅接收到部分請求,但是一旦伺服器并沒有拒絕該請求,用戶端應該繼續發送其餘的請求。 |
101 Switching Protocols | 伺服器轉換協定:伺服器将遵從客戶的請求轉換到另外一種協定。 |
2xx: 成功
消息: | 描述: |
---|---|
200 OK | 請求成功(其後是對GET和POST請求的應答文檔。) |
201 Created | 請求被建立完成,同時新的資源被建立。 |
202 Accepted | 供處理的請求已被接受,但是處理未完成。 |
203 Non-authoritative Information | 文檔已經正常地傳回,但一些應答頭可能不正确,因為使用的是文檔的拷貝。 |
204 No Content | 沒有新文檔。浏覽器應該繼續顯示原來的文檔。如果使用者定期地重新整理頁面,而Servlet可以确定使用者文檔足夠新,這個狀态代碼是很有用的。 |
205 Reset Content | 沒有新文檔。但浏覽器應該重置它所顯示的内容。用來強制浏覽器清除表單輸入内容。 |
206 Partial Content | 客戶發送了一個帶有Range頭的GET請求,伺服器完成了它。 |
3xx: 重定向
消息: | 描述: |
---|---|
300 Multiple Choices | 多重選擇。連結清單。使用者可以選擇某連結到達目的地。最多允許五個位址。 |
301 Moved Permanently | 所請求的頁面已經轉移至新的url。 |
302 Found | 所請求的頁面已經臨時轉移至新的url。 |
303 See Other | 所請求的頁面可在别的url下被找到。 |
304 Not Modified | 未按預期修改文檔。用戶端有緩沖的文檔并發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶隻想比指定日期更新的文檔)。伺服器告訴客戶,原來緩沖的文檔還可以繼續使用。 |
305 Use Proxy | 客戶請求的文檔應該通過Location頭所指明的代理伺服器提取。 |
306 Unused | 此代碼被用于前一版本。目前已不再使用,但是代碼依然被保留。 |
307 Temporary Redirect | 被請求的頁面已經臨時移至新的url。 |
4xx: 用戶端錯誤
消息: | 描述: |
---|---|
400 Bad Request | 伺服器未能了解請求。 |
401 Unauthorized | 被請求的頁面需要使用者名和密碼。 |
402 Payment Required | 此代碼尚無法使用。 |
403 Forbidden | 對被請求頁面的通路被禁止。 |
404 Not Found | 伺服器無法找到被請求的頁面。 |
405 Method Not Allowed | 請求中指定的方法不被允許。 |
406 Not Acceptable | 伺服器生成的響應無法被用戶端所接受。 |
407 Proxy Authentication Required | 使用者必須首先使用代理伺服器進行驗證,這樣請求才會被處理。 |
408 Request Timeout | 請求超出了伺服器的等待時間。 |
409 Conflict | 由于沖突,請求無法被完成。 |
410 Gone | 被請求的頁面不可用。 |
411 Length Required | "Content-Length" 未被定義。如果無此内容,伺服器不會接受請求。 |
412 Precondition Failed | 請求中的前提條件被伺服器評估為失敗。 |
413 Request Entity Too Large | 由于所請求的實體的太大,伺服器不會接受請求。 |
414 Request-url Too Long | 由于url太長,伺服器不會接受請求。當post請求被轉換為帶有很長的查詢資訊的get請求時,就會發生這種情況。 |
415 Unsupported Media Type | 由于媒介類型不被支援,伺服器不會接受請求。 |
416 | 伺服器不能滿足客戶在請求中指定的Range頭。 |
417 Expectation Failed |
5xx: 伺服器錯誤
消息: | 描述: |
---|---|
500 Internal Server Error | 請求未完成。伺服器遇到不可預知的情況。 |
501 Not Implemented | 請求未完成。伺服器不支援所請求的功能。 |
502 Bad Gateway | 請求未完成。伺服器從上遊伺服器收到一個無效的響應。 |
503 Service Unavailable | 請求未完成。伺服器臨時過載或當機。 |
504 Gateway Timeout | 網關逾時。 |
505 HTTP Version Not Supported | 伺服器不支援請求中指明的HTTP協定版本。 |