前言: 小白秋招準備第三彈...這次主要總結和複習了ajax請求以及跨域的一些問題。因為實習後,直接用Jquery或axios傳送請求,原生的方法都有點生疏了,再次複習。另外,還總結了一些面試常見的演算法問題,關於演算法我會堅持練習並記錄下較好的點並不斷在github更新。 一起找工作的、喜歡的小夥伴歡迎Star
Ajax && Jsonp跨域
Ajax
通過Jquery或者axios傳送Ajax請求
//jquery
$.get('//discovery.vip.com',{
'click':3,
'name':'job'
},(data) => {
console.log(data);
})
// $.get() 與 $.post()基本一致,第一個引數url,第二個引數是資料(可選)
// 第三個引數是回撥函式
//axios 與juqery很相似,只不過它是支援Promise的一種方法
axios.get('//discovery.vip.com').then((data)=>{
console.log(data);
}).catch(error) {
console.log(error);
}
//可選請求
axios.get('//discovery.vip.com',{
params:{
id:12345
}
}).then((data)=>{
console.log(data);
}).catch(err => {
console.log(err);
})
複製程式碼
原生Ajax方法
原生Ajax是建立在XMLHttpRequest請求上,這個現代瀏覽器支援,不支援的話,得使用ActiveX物件 new一個物件
if(window.XMLHttpRequest) {
var Req = new XMLHttpRequest();
}else {
var Req = new ActiveX('Microsoft.XMLHTTP');
}
複製程式碼
物件建立好之後,即使傳送請求了open()
和send()
其中open
規定格式,send()
正式傳送
//get方法
//get方法,send不需要加內容,open的第三個參數列示是否非同步,預設為true
Req.open('get','//discovery.vip.com',true);
Req.onreadystatechange = function() {
if(Req.readyState === 4 && Req.status === 200) {
document.getElementById('root').innerHtml = Req.responseText;
}
}
Req.send();
//post
Req.open('post','//discovery.vip.com',true);
Req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
Req.onreadystatechange = function() {
if(Req.readyState === 4 && Req.status === 200) {
document.getElementById('root').innerHtml = Req.responseText;
}
}
Req.send("fname=Henry&lname=Ford");
複製程式碼
注意這裡post的方法設定了請求頭,這裡對請求頭簡單說一下
Content-type,application/x-www-form-urlencoded
的方式
這種方式最常見的方式,原生form表單的提交方式。 提交的時候,將會以key1=value&key2=value&key3=value
的方式進行編碼
multipart/form-data
這個看起來也是比較熟悉的,因為的確也很常見呀~ 當要使用檔案上傳元件時,必須讓form的entyped的值等於這個
application/json
格式
這個就是json的格式,用來告訴伺服器訊息主體是序列化後的JSON字串
跨域
跨域最簡單、乾淨的方式,應該是W3C規定的CROS跨域了。 這個在使用fidder進行抓包除錯的時候,使用filter來處理跨域的問題,算是很方便了。
方法就是在返回資料上加個頭 set Response header
Access-Control-Allow-Origin,*
這個表示允許任意域名跨域
Access-Control-Allow-Origin,192.168.1.110:8080
允許指定域名跨域
當然這個不是重點,下面主要說一下Jsop的跨域
Jsonp
Jsonp跨域也是需要後端伺服器配合的,原來就是雖然Ajax請求不允許跨域,但是<script>、<img>
等是可以跨域的
//jquery封裝的跨域
$.ajax({
url:'//discovery.vip.com',
method: 'GET',
dataType: 'jsonp',
success: function (data) {
var result = JSON.stringify(data);
$('#test').val(result);
}
})
複製程式碼
注意:JSONP的一個限制,就是隻能使用get
請求,因為<script src>
就支援get
請求呀。
好了,以上的方法會返回一個隨機的函式名,Jquery內部處理得到。如果想要自己規定,也是可以的
$.ajax({
url:'//discovery.vip.com',
method:'GET',
dataType:'jsonp',
jsonpCallback:'showData',
success:function(data) {
console.log('success')
}
})
function showData(data) {
var result = JSON.stringify(data);
$("#test").val(result);
}
複製程式碼
這裡就可以看的更清楚一些了,其實返回的資料是showData({...})
。 因為我們設定了函式,所以就直接執行函式。
就是因為這樣的道理,我們完全可以自己做一個script標籤,動態新增src來請求資料,實現自己的jsonp
。
演算法
統計數字
問題描述
計算數字k在0到n中的出現的次數,k可能是0~9的一個值
例如n=12,k=1,在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我們發現1出現了5次 (1, 10, 11, 12)
解析:
最簡單的方法就是遍歷了,當然高階方法這裡不探討。那麼簡單的遍歷又有什麼問題呢? 那就是遇到了比如111
這樣的數字。
我們可以使用indexOf
來判斷是否出現過,但是出現了多少次該怎麼判斷?
說一個思路,使用split
方法,具體實現如下
const digitCounts = function (k, n) {
let num = 0;
for(let i = 0; i<=n;i++){
if(String(i).indexOf(k) !== -1) {
num += (String(i).split(k).length-1)
}
}
return num
}
複製程式碼
快速排序和二分查詢
一般的排序,使用Array.sort()
可以很方便的解決,所以對於前端來說,主要掌握快排和二分查詢是基礎和必要的。其他的可以有興趣再研究好了
快排
只用遞迴實現,基本思路:
- 拿出一個數字;
- 逐一和剩下數字比較,比這個數字小的放左邊,大的放右邊
- 對左邊和右邊再使用同樣的比較方法
- 直到比較結束
程式碼實現如下:
function quickSort(arr) {
if(arr.length <= 1) {
return arr;
}
let left = [];
let right = [];
let cur = arr.splice(0,1);
for(let i = 0; i<arr.length; i++) {
if(arr[i] < cur) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat(cur,quickSort(right));
}
複製程式碼
二分查詢
原理很簡單了,就是找中間數,複雜度(log(N)),前提是必須在有序數列中查詢
- 在一個範圍內,將target與中間值比較
- 如果大了,在大的範圍進行查詢;如果小了,在小的範圍查詢;
- 重複上面的方法
用兩種方法,一種是迴圈,一種是遞迴來實現
//迴圈實現
function binarySearch(arr,target) {
let low = 0;
let high = arr.length - 1;
while(low <= high) {
let mid = parseInt((high+low)/2);
if(target === arr[mid]) {
return `找到了${target},位置在${mid}`
} else if (target > Math.floor(high/2)) {
low = mid+1;
} else {
high = mid-1;
}
}
return false;
}
複製程式碼
這裡需要注意low
high
的取值和變化
- 中間值的取法`parseInt((high+low)/2)
- 當在另一個區間的時候,不能用
low = mid
或high=mid
,因為這樣邊界值就會進入死迴圈。
//遞迴的方法
function binarySearch(arr,target,low,high) {
let mid = parseInt((low+high)/2);
if(arr[mid] === target) {
return `找到了${target},位置在${mid}`
} else if(target > arr[mid]) {
return binarySearch(arr,target,mid+1,high)
} else {
return binarySearch(arr,target,low,high-1)
}
return -1
}
複製程式碼
二分查詢真題,尋找二維陣列內的值
在一個二維陣列中,每一行都按照從左到右遞增,每一列都從上到下遞增的順序排序,完成一個函式,輸入這個二維陣列和一個整數,判斷陣列中是否含有該整數
思路是一樣的,只不過從一維變成了二維,我們遍歷思路可以這樣子:
- 選取第一行的最後一個進行判斷(這個是第一行中最大的)
- 如果目標大於該值,行數加1,遍歷第二行(因為每列都是遞增的)
- 如果目標小於該值,則在這一行中進行查詢
- 迴圈以上步驟
function findTarget(arr,target) {
let i = 0;
let j = arr[i].length -1;
while(i < arr.length && j>=0) { //i是隻增不減的,j是隻減不增的,就是從矩陣右上角向下查詢的過程
if(target < arr[i][j]) {
j--;
} else if (target > arr[i][j]) {
i++;
} else {
return `找到了,位置在${i},${j}`
}
}
return `(${i},${j})`
}
arr=[
[1,2,3,4],
[5,9,10,11],
[13,20,21,23]] //測試
複製程式碼
後記
嗯..今天先到這裡吧
演算法算是比較頭疼的,因為非科班出身,對於前端演算法的深度過深對於實際效率而言並不高(為了以後深入發展當然要好好研究,可是如果為了近期秋招、面試,似乎不如適可而止,花更多時間在應該的地方上)
所以後期會積累常見、常考的演算法題目,一一記錄,共同成長... 明天再更