>### A.今天學什么?
#### 1.正則補充
- ##### 1.1 正則的一些屬性
- global -g 是否全文搜索,默認false
- ignore -i 是否忽略大小寫,默認false
- test() --> 字符串中是否存在匹配正則表達式的字符串,用來做局部匹配,所以不要加全局搜索
- lastIndex --> 當前表達式匹配內容的最后一個字符的下一個位置
- 如果加了g,全局匹配。會有一個lastIndex屬性,用于獲取下一個要匹配的下標
```
// body
<body>
<script>
// global -g 是否全文搜索,默認false
// ignore -i 是否忽略大小寫,默認false
var str = "hello chunjue LL";
var RE = /l/ig;
console.log(str.replace(RE,"*"));
// test() --> 字符串中是否存在匹配正則表達式的字符串,用來做局部匹配,所以不要加全局搜索
// lastIndex --> 當前表達式匹配內容的最后一個字符的下一個位置
var str2 ="ab";
var RE2 = /[a-z]/;
// 如果加了g,全局匹配。會有一個lastIndex屬性,用于獲取下一個要匹配的下標
// 匹配a的時候,得到的lastIndex=1,匹配b的時候,得到的lastIndex=2,然而下標為2的地方并沒有值,所以返回false
while (RE2.test(str2)){
console.log(RE2.lastIndex); // 1 2
}
</script>
</body>
```
- ##### 1.2 貪婪模式
- 貪婪模式 --> 默認會取量詞中最大的值
- 懶惰模式 --> ? 取消貪婪模式 --> 只要符合正則就停下來
```
// body
<body>
<script>
var a = "123456abc";
var RE = /\d{3,6}/;
// 貪婪模式 --> 默認會取量詞中最大的值
console.log(a.replace(RE,"*")); // *abc 可以看到,123456一起被替換為*
// 懶惰模式 --> ? 取消貪婪模式 --> 只要符合正則就停下來
var noRE = /\d{3,6}?/;
console.log(a.replace(noRE,"*")); // *456abc
</script>
</body>
```
#### 2.js內置對象--日期
- ##### 2.1方法介紹
- 獲得日期對象 --> var oDate = new Date();
- 獲得年 --> var year = oDate.getFullYear();
- 獲得月 --> var month = oDate.getMonth()+1; 月 getMonth() 月份從0開始,所以要加1
- 獲得日 --> var date = oDate.getDate();
- 獲得星期 --> var day = oDate.getDay();
- 獲得小時、分鐘、秒
- var hour = oDate.getHours();
- var minute = oDate.getMinutes();
- var second = oDate.getSeconds();
```
// body
<body>
<script>
var oDate = new Date();
console.log(oDate);
// 年
var year = oDate.getFullYear();
console.log(year);
// 月 getMonth() 月份從0開始,所以要加1
var month = oDate.getMonth()+1;
console.log(month);
// 日
var date = oDate.getDate();
console.log(date);
// 周幾
var day = oDate.getDay();
console.log(day);
// 小時 分鐘 秒
var hour = oDate.getHours();
var minute = oDate.getMinutes();
var second = oDate.getSeconds();
console.log(hour+":"+minute+":"+second);
</script>
</body>
```
- ##### 2.2 日期對象搭配定時器制作頁面時間
```
// body
<body>
<div>
<img src="images/0.png" alt="">
<img src="images/0.png" alt="">
<img src="images/0.png" alt="">
<img src="images/0.png" alt="">
<img src="images/0.png" alt="">
<img src="images/0.png" alt="">
</div>
<script>
function showTime() {
var clocks = document.getElementsByTagName("img");
var oDate = new Date();
var hour = oDate.getHours();
var minute = oDate.getMinutes();
var second = oDate.getSeconds();
// 1.將時間變為字符串,拼接起來
// 2.將它們分割成數組
// 3.讓allTime中對應的值顯示對應的圖片
// 如果時、分、秒 < 10,則在數字之前補一個0 --> 比如 09
function add(time) {
if (time < 10){
// 拼接為字符串
return "0"+time;
}
else{
return time+"";
}
}
var allTime = add(hour)+add(minute)+add(second);
console.log(allTime);
for (var i = 0;i < allTime.length;i++){
clocks[i].src = "images/"+allTime[i]+".png";
}
}
// 將顯示時間整個封裝為一個方法,利用定時器,每秒調用一次方法
// 在一開始就先調用一次showTime()方法
showTime();
setInterval(showTime,1000);
</script>
</body>
```
#### 3.Ajax --> 異步局部刷新頁面技術
- ##### 3.1 json數據
- JavaScript Object Notation(JavaScript 對象表示法)
- JSON 是存儲和交換文本信息的語法。類似 XML。
- JSON 比 XML 更小、更快,更易解析。
- 例如:{ "data": { "content": "getTest"} }
- json就是一種鍵值對,key必須雙引號引起來
- json對象可以通過 json.key 獲得 value值,和obj獲得屬性一樣
- JSON.parse(str) --> 將json格式的字符串轉換為json對象
- JSON.stringify(jsonObj) --> 將JSON對象轉為字符串。
- ##### 3.2 原生js的Ajax如何使用
- 1.創建ajax的核心對象 --> var xhr = new XMLHttpRequest();
- 2.建立與服務器的連接 --> xhr.open(method,url,true) --> 第一個參數為請求方式,第三個參數是是否異步,默認為異步 true
- 3.向服務器發送請求 --> xhr.send()
- 4.服務器端響應 xhr.onreadystatechange = function (){}
- 狀態碼要求:xhr.readyState === 4 && xhr.status === 200
- 接收服務器端返回數據 --> var response = xhr.responseText; 得到的是一個字符串
- ##### 3.3 AJAX 狀態值(readyState)與狀態碼(status)詳解
- AJAX運行步驟與狀態值(readyState)說明
- 在AJAX實際運行當中,對于訪問XMLHttpRequest(XHR)時并不是一次完成的,而是分別經歷了多種狀態后取得的結果,對于這種狀態在AJAX中共有5種,分別是。
- 0 - (未初始化)還沒有調用send()方法
- 1 - (載入)已調用send()方法,正在發送請求
- 2 - (載入完成)send()方法執行完成
- 3 - (交互)正在解析響應內容
- 4 - (完成)響應內容解析完成,可以在客戶端調用了
- 對于上面的狀態,其中“0”狀態是在定義后自動具有的狀態值,而對于成功訪問的狀態(得到信息)我們大多數采用“4”進行判斷。
- AJAX狀態碼(status)說明
- 1**:請求收到,繼續處理
- 2**:操作成功收到,分析、接受
- 3**:完成此請求必須進一步處理
- 4**:請求包含一個錯誤語法或不能完成
- 5**:服務器執行一個完全有效請求失敗
- 100——客戶必須繼續發出請求
- 101——客戶要求服務器根據請求轉換HTTP協議版本
- 200——交易成功
- 201——提示知道新文件的URL
- 202——接受和處理、但處理未完成
- 203——返回信息不確定或不完整
- 204——請求收到,但返回信息為空
- 205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
- 206——服務器已經完成了部分用戶的GET請求
- 300——請求的資源可在多處得到
- 301——刪除請求數據
- 302——在其他地址發現了請求數據
- 303——建議客戶訪問其他URL或訪問方式
- 304——客戶端已經執行了GET,但文件未變化
- 305——請求的資源必須從服務器指定的地址得到
- 306——前一版本HTTP中使用的代碼,現行版本中不再使用
- 307——申明請求的資源臨時性刪除
- 400——錯誤請求,如語法錯誤
- 401——請求授權失敗
- 402——保留有效ChargeTo頭響應
- 403——請求不允許
- 404——沒有發現文件、查詢或URl
- 405——用戶在Request-Line字段定義的方法不允許
- 406——根據用戶發送的Accept拖,請求資源不可訪問
- 407——類似401,用戶必須首先在代理服務器上得到授權
- 408——客戶端沒有在用戶指定的餓時間內完成請求
- 409——對當前資源狀態,請求不能完成
- 410——服務器上不再有此資源且無進一步的參考地址
- 411——服務器拒絕用戶定義的Content-Length屬性請求
- 412——一個或多個請求頭字段在當前請求中錯誤
- 413——請求的資源大于服務器允許的大小
- 414——請求的資源URL長于服務器允許的長度
- 415——請求資源不支持請求項目格式
- 416——請求中包含Range請求頭字段,在當前請求資源范圍內沒有range指示值,請求也不- 包含If-Range請求頭字段
- 417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求
- 500——服務器產生內部錯誤
- 501——服務器不支持請求的函數
- 502——服務器暫時不可用,有時是為了防止發生系統過載
- 503——服務器過載或暫停維修
- 504——關口過載,服務器使用另一個關口或服務來響應用戶,等待時間設定值較長
- 505——服務器不支持或拒絕支請求頭中指定的HTTP版本
```
// body
<body>
<div id="text"></div>
<script>
// ajax --> 就是向服務器端取數據的一種技術,能做到頁面的局部刷新,是異步的
// json數據,就是一種鍵值對的數據格式,key必須雙引號引起來
var json = {
"name" : "hello world",
"arr" : [1,2,3],
"age" : 19
};
// 如何使用ajax
// 1.創建ajax的核心對象
var xhr = new XMLHttpRequest();
var text = document.getElementById("text");
// 2.建立與服務器的連接
// xhr.open(method,url,true) --> 第一個參數為請求方式,第三個參數是是否異步,默認為異步 true
var url = "https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/getTest";
xhr.open("get",url,true); // true為默認值
// 3.向服務器發送請求 --> xhr.send()
xhr.send();
// 4.服務器端響應 xhr.onreadystatechange = function (){}
// xhr.readyState和xhr.status為其狀態碼
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
// JSON.parse();將json格式的字符串轉為json對象
var response = JSON.parse(xhr.responseText);
console.log(typeof response);
// 獲得key為data的value,然后再從value中獲得key為content的value
// json可以這樣用 --> json.key = value
text.innerHTML = response.data.content;
}
}
</script>
</body>
```
- ##### 3.4 jquery -- ajax
- url --> 請求地址
- type --> 請求方式,默認是'GET',常用的還有'POST'
- dataType --> 設置返回的數據格式,常用的是'json'格式,也可以設置為'html'等
- async --> 設置是否異步,默認值是'true',表示異步
- .done(function(data){}) --> 設置請求成功后的回調函數
- .fail(function(){}) --> 設置請求失敗后的回調函數
- ##### 3.5 jquery的ajax的get請求
```
// 先要使用script標簽引入jquery,可以在百度CDN上查找jquery靜態資源引入
地址為:http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js
// body
<body>
<script>
// jquery -- ajax
// url --> 請求地址
// type --> 請求方式,默認是'GET',常用的還有'POST'
// dataType --> 設置返回的數據格式,常用的是'json'格式,也可以設置為'html'等
// async --> 設置是否異步,默認值是'true',表示異步
// .done(function(data){}) --> 設置請求成功后的回調函數
// .fail(function(){}) --> 設置請求失敗后的回調函數
$.ajax({
url: 'https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/getTest',
type: 'GET',
dataType: 'json',
data:{'aa':1}
})
.done(function(data) {
alert(JSON.stringify(data));
})
.fail(function() {
alert('服務器超時,請重試!');
});
setTimeout(1000);
// 更加簡單的簡寫方式
var url = "https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/getTest";
$.get(url,function (data) {
console.log(JSON.stringify(data));
}).fail(function () {
alert("服務器超時,請重試!");
})
</script>
</body>
```
- ##### 3.6 jquery的ajax的post請求
```
// body
<body>
<script>
// post 請求方式,更改type即可
$.ajax({
url: 'https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/postTest',
type: 'POST',
dataType: 'json',
data:{'aa':1}
})
.done(function(data) {
alert(JSON.stringify(data));
})
.fail(function() {
alert('服務器超時,請重試!');
});
setTimeout(1000);
// 更加簡單的簡寫方式
var url = "https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/postTest";
// post請求簡寫時就寫 $.post
$.post(url,function (data) {
console.log(JSON.stringify(data));
}).fail(function () {
alert("服務器超時,請重試!");
})
</script>
</body>
```
- ##### 3.7 axios的ajax請求
```
// body
<body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// post方法同理
var url = "https://www.easy-mock.com/mock/5b3ae0bfd294426e05198b5a/AjaxTest/getTest";
axios.get(url).then(function (succuss) {
console.log(succuss.request.responseText);
}).catch(function (err) {
console.log(err);
})
</script>
</body>
```
#### 4.跨域
- ##### 4.1 script標簽實現跨域
- 要理解跨域,先要了解一下“同源策略”。所謂同源是指,域名,協議,端口相同。所謂“同源策略“,簡單的說就是基于安全考慮,當前域不能訪問其他域的東西。
- 協議: http or https
- 域名: www.baidu.com or www.hao123.com
- 端口號: https://www.a.com:8080 or https://www.a.com:9090
- img標簽的src(獲取圖片),link 的href(獲取css),script 的src(獲取javascript)這三個都不符合同源策略,它們可以跨域獲取數據。
- 這里要介紹的JSONP就是利用 script 的src來實現跨域獲取數據的。
- JSONP實現跨域請求的原理簡單的說,就是動態創建 script 標簽,然后利用 script 的src 不受同源策略約束來跨域獲取數據。
- JSONP 由兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面中調用的函數。回調函數的名字一般是在請求中指定的。而數據就是傳入回調函數中的 JSON 數據。
- script標簽,可以跨域請求靜態資源等,所以用script實現跨域就是鉆這個漏洞
```
<body>
<input type="text" id="song" name="">
<input type="button" id="song_search" value="歌曲搜索" name="">
<br />
<div style="width:300px;height:300px;background:pink" id="song_list">
<ul class="list"></ul>
</div>
<script type="text/javascript" src="../../static/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
// <img>的src(獲取圖片),<link>的href(獲取css),<script>的src(獲取javascript)這三個都不符合同源策略,它們可以跨域獲取數據。
// 這里要介紹的JSONP就是利用<script>的src來實現跨域獲取數據的。
// JSONP實現跨域請求的原理簡單的說,就是動態創建<script>標簽,然后利用<script>的src 不受同源策略約束來跨域獲取數據。
// JSONP 由兩部分組成:回調函數和數據。回調函數是當響應到來時應該在頁面中調用的函數。回調函數的名字一般是在請求中指定的。而數據就是傳入回調函數中的 JSON 數據。
// script標簽,可以跨域請求靜態資源等,所以用script實現跨域就是鉆這個漏洞
// handleResponse 用于處理服務器返回數據,回調函數
function handleResponse(response){
console.log(response.s);
for (var i = 0;i < response.s.length;i++){
var $li = $('<li>' + response.s[i] + '</li>');
$li.insertAfter(".list");
}
}
$("#song_search").on("click",function(){
var keyword=$("#song").val();
if(keyword === undefined || keyword === ""){
alert("歌曲搜索不能為空");
return false;
}else{
// 動態創建<script>標簽,設置其src,回調函數在src中設置
// claaback=handleResponse --> 自動調用定義的handleResponse方法對返回的data進行操作
// handleResponse即為回調函數
var url = "https://sug.so.#/suggest?word="+keyword+"&callback=handleResponse";
// 創建script標簽,設置其屬性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script標簽加入head,此時調用開始
document.getElementsByTagName('head')[0].appendChild(script);
}
});
</script>
</body>
```
- ##### 4.2 jquery實現跨域及jquery的幾個參數
- dataType(string)
- "xml": 返回 XML 文檔,可用 jQuery 處理。
- "html": 返回純文本 HTML 信息;包含的script標簽會在插入dom時執行。
- "script": 返回純文本 JavaScript 代碼。
- "json": 返回 JSON 數據 。
- "jsonp": JSONP 格式。開啟跨域
- "text": 返回純文本字符串
- jsonp(string) --> 一般不用,只定義一個jsonpCallback即可
- 回掉函數名的參數名,默認callback,服務端通過它來獲取到回掉函數名
- jsonpCallback(string) --> 回掉函數名,默認jquery自動生成
- 指定jsonpCallback時可以將回掉函數寫在ajax外面做其他操作,不指定時不能這樣做,只能在success里做操作
- 定義jsonp和jsonpCallback后,后端返回數據,需要使用 jsonpCallback的值+"{return json 返回的json }"這樣包起來
- 一般使用 String callback = Request.QueryString["callback"].ToString(); 獲取,callback即為jsonp的值
- jquery實現跨域,將dataType屬性改為jsonp即可
```
// body
<body>
<script>
// jquery跨域,將dataType的屬性改為jsonp即可
/**
*@dataType (String)
*"xml": 返回 XML 文檔,可用 jQuery 處理。
*"html": 返回純文本 HTML 信息;包含的script標簽會在插入dom時執行。
*"script": 返回純文本 JavaScript 代碼。"json": 返回 JSON 數據 。
*"jsonp": JSONP 格式。使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數。
*"text": 返回純文本字符串
*/
/**
*@jsonp (String)在一個jsonp請求中重寫回調函數的名字。
*這個值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分,
*比如{jsonp:'onJsonPLoad'}會導致將"onJsonPLoad=?"傳給服務器。
*/
/**
*@jsonpCallback (String)
*為jsonp請求指定一個回調函數名。這個值將用來取代jQuery自動生成的隨機函數名。
*這主要用來讓jQuery生成度獨特的函數名,這樣管理請求更容易,也能方便地提供回調函數和錯誤處理。
*你也可以在想讓瀏覽器緩存GET請求的時候,指定這個回調函數名。
*/
$.ajax({
url:"https://api.douban.com/v2/book/search?q=javascript&count=1",
type:"get",
dataType:"jsonp",
jsonpCallback:"a"
})
.done(function(data){
console.log(JSON.stringify(data));
})
.fail(function(){
console.log('error');
})
</script>
</body>
```