想沉澱開發過程中遇到的問題,避免重複的查詢。接下來,我會一點點地將遇到的問題記錄在這裏。希望這本問題集能減少你在遇到問題時在搜索引擎中漫無目的且耗時地搜索花費的時間,提升開發效率!
css 設置div寬高比1:2
html {height: 100%;width: 100%;}
body {
height: 100%;
width: 100%;
position: relative;
/*display: flex;
justify-content: center;
align-items: center;*/
}
.mydiv {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: 10vw;
height: 20vw;
}
.mydiv #box {
background: #ccc;
height: 100%;
width: 100%;
}
<div class="mydiv">
<div id="box"></div>
</div>
判斷兩個小數是否相等
用等於號是肯定不行的。判斷兩個小數是否相等要用它們的差值和一個很小的小數進行比較,如果小於這個這個小數,則認爲兩者相等。ES6新增了一個Math.EPSILON
極小的常量屬性,如比較0.1+0.2
是否等於0.3:
0.1+0.2-0.3 < Number.EPSILON
Number.EPSILON實際上是 JavaScript 能夠表示的最小精度。誤差如果小於這個值,就可以認爲已經沒有意義了,即不存在誤差了。
Number.EPSILON可以用來設置“能夠接受的誤差範圍”。比如,誤差範圍設爲 2 的-50 次方(即Number.EPSILON * Math.pow(2, 2)),即如果兩個浮點數的差小於這個值,我們就認爲這兩個浮點數相等。
5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2)
Git Rebase
Git Bebase 通常用在如下兩點:
- 合併多次提交紀錄
- 分支合併
- 當我們在一個過時的分支上面開發的時候,執行 rebase 以此同步 master 分支最新變動;
- 假如我們要啓動一個放置了很久的並行工作,現在有時間來繼續這件事情,很顯然這個分支已經落後了。這時候需要在最新的基準上面開始工作,所以 rebase 是最合適的選擇。
注意:
只要你的分支上需要 rebase 的所有 commits 歷史還沒有被 push 過,就可以安全地使用 git-rebase來操作。
找兩個數組中不重複的部分
function getArrDifference(arr1, arr2) {
return arr1.concat(arr2).filter(function(v, i, arr) {
return arr.indexOf(v) === arr.lastIndexOf(v);
});
}
將時間字符串轉換爲Date,並計算該時間之後的日期
let nowDate = new Date('2019-06-21');
nowDate.setTime(nowDate.getTime()+((30-1)*24*60*60*1000));//往後推30天
let endDate = nowDate.getFullYear()+"-"+(nowDate.getMonth()+1)+"-"+nowDate.getDate();//2019-06-20
事件綁定函數
function bindEvent(elem, type, selector, fn) {
// 這樣處理,可接收兩種調用方式 bindEvent(div1, 'click', 'a', function () {...}) 和 bindEvent(div1, 'click', function () {...}) 這兩種
if (fn == null) {
fn = selector
selector = null
}
// 綁定事件
elem.addEventListener(type, function (e) {
var target
if (selector) {
// 有 selector 說明需要做事件代理
// 獲取觸發時間的元素,即 e.target
target = e.target
// 看是否符合 selector 這個條件
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
// 無 selector ,說明不需要事件代理
fn(e)
}
})
}
- 使用
// 使用代理,bindEvent 多一個 'a' 參數
var div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', function (e) {
console.log(this.innerHTML)
})
// 不使用代理
var a = document.getElementById('a1')
bindEvent(div1, 'click', function (e) {
console.log(a.innerHTML)
})
使用代理的優點如下:
- 使代碼簡潔
- 減少瀏覽器的內存佔用
居中
水平居中
- 使用margin:0 auto配合元素的width
#center{
width: 100px;//元素需要固定寬度
margin: 0 auto;//當元素處於position:absolute時,無效。需要將left和right都設爲0纔可以。
}
- 使用絕對定位配合margin
#center{
width: 100px;//需要固定居中元素的寬度
position: absolute;
left: 50%;
margin-left: -100px; //值爲width的一半
}
- 塊級父元素讓行內元素居中
#center{
text-align: center;//居中元素必須是inline或者設置爲inline-block
}
- 利用relative定位與行內樣式
#main{
display: inline-block;//將#main與#center全部設置爲inline-block,將包裹他們的內容
position: relative;
left: 50%;//將#main往右移其寬度的50%
}
#center{
display: inline-block;
position: relative;
right: 50%;//將#center往左移其寬度的50%,最終#center元素居中
}
- 通過transform進行設置
#main{
position: relative;
}
#center{
position: absolute;
left: 50%;
transform: translateX(-50%);//首先left:50%先右移#main50%的寬度,然後通過translateX(-50%)在左移本身50%的寬度
}
- flex-box
#main{
display: flex; //父元素設置爲flex
justify-content: center;
}
垂直居中
- line-height,僅適合小元素,單行文本
#main{
height: 200px;//居中元素的父元素必須要設置準確height數值
line-height: 200px;
}
- absolute搭配margin
#main{
position: relative;
}
#center{
height: 50px; //需要固定居中元素的height值
position: absolute;
top: 50%;
margin-top: -25px; //值爲height的一半
}
或
#center{
height: 50px; //需要固定居中元素的height值
position: absolute;
top: calc(50% - 25px);
}
- table-cell配合vertical-align
#main{
height: 100%;
display: table;//父元素設置爲display:table;
}
#center{//子元素設置爲display:table-cell
display: table-cell;
vertical-align: middle;
}
- transform
#main{
height:100%;
position: relative;
}
#center{
position: absolute;//居中元素被設置爲absolute
top: 50%;//首先top:50%先下移#main50%的高度
transform: translateY(-50%);//然後通過translateY(-50%)在上移本身50%的高度
}
或
#center{
margin:50% auto 0; //下移到#main50%的高度
transform: translateY(-50%);
}
或
#center{
margin:50vh auto 0; //下移到視口50%的高度
transform: translateY(-50%);
}
- 父元素設置爲 flex-box
#main {
height:100%;
display: flex;
align-items: center;
}
正則表達式大全
校驗數字的表達式
-
數字:
^[0-9]*$
-
n位的數字:
^d{n}$
-
至少n位的數字:
^d{n,}$
-
m-n位的數字:
^d{m,n}$
-
零和非零開頭的數字:
^(0|[1-9][0-9]*)$
-
非零開頭的最多帶兩位小數的數字:
^([1-9][0-9]*)+(.[0-9]{1,2})?$
-
帶1-2位小數的正數或負數:
^(-)?d+(.d{1,2})?$
-
正數、負數、和小數:
^(-|+)?d+(.d+)?$
-
有兩位小數的正實數:
^[0-9]+(.[0-9]{2})?$
-
有1~3位小數的正實數:
^[0-9]+(.[0-9]{1,3})?$
-
非零的正整數:
^[1-9]d*$ 或 ^([1-9][0-9]*){1,3}$
或^+?[1-9][0-9]*$
-
非零的負整數:
^-[1-9][]0-9"*$
或^-[1-9]d*$
-
非負整數:
^d+$
或^[1-9]d*|0$
-
非正整數:
^-[1-9]d*|0$
或^((-d+)|(0+))$
-
非負浮點數:
^d+(.d+)?$
或^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$
-
非正浮點數:
^((-d+(.d+)?)|(0+(.0+)?))$
或^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$
-
正浮點數:
^[1-9]d*.d*|0.d*[1-9]d*$
或^(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*))$
-
負浮點數:
^-([1-9]d*.d*|0.d*[1-9]d*)$
或^(-(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*)))$
-
浮點數:
^(-?d+)(.d+)?$
或^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$
校驗字符的表達式
- 漢字:
^[\u4e00-\u9fa5]{0,}$
- 英文和數字:
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
- 長度爲3-20的所有字符:
^.{3,20}$
- 由26個英文字母組成的字符串:
^[A-Za-z]+$
- 由26個大寫英文字母組成的字符串:
^[A-Z]+$
- 由26個小寫英文字母組成的字符串:
^[a-z]+$
- 由數字和26個英文字母組成的字符串:
^[A-Za-z0-9]+$
- 由數字、26個英文字母或者下劃線組成的字符串:
^\w+$ 或 ^\w{3,20}$
- 中文、英文、數字包括下劃線:
^[\u4E00-\u9FA5A-Za-z0-9_]+$
- 中文、英文、數字但不包括下劃線等符號:
^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11 可以輸入含有^%&',;=?$\"
等字符:[^%&',;=?$\x22]+
12 禁止輸入含有~的字符:[^~\x22]+
特殊需求表達式
- Email地址:
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
- 域名:
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
- InternetURL:
[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
- 手機號碼:
^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\d{8}$ (由於工信部放號段不定時,所以建議使用泛解析 ^([1][3,4,5,6,7,8,9])\d{9}$)
- 電話號碼(“XXX-XXXXXXX”、“XXXX-XXXXXXXX”、“XXX-XXXXXXX”、“XXX-XXXXXXXX”、"XXXXXXX"和"XXXXXXXX):
^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
- 國內電話號碼(0511-4405222、021-87888822):
\d{3}-\d{8}|\d{4}-\d{7}
- 18位身份證號碼(數字、字母x結尾):
^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
- 帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
- 密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):
^[a-zA-Z]\w{5,17}$
- 強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
- 日期格式:
^\d{4}-\d{1,2}-\d{1,2}
- 一年的12個月(01~09和1~12):
^(0?[1-9]|1[0-2])$
- 一個月的31天(01~09和1~31):
^((0?[1-9])|((1|2)[0-9])|30|31)$
- 錢的輸入格式:
- 有四種錢的表示形式我們可以接受:“10000.00” 和 “10,000.00”, 和沒有 “分” 的 “10000” 和 “10,000”:
^[1-9][0-9]*$
- 這表示任意一個不以0開頭的數字,但是,這也意味着一個字符"0"不通過,所以我們採用下面的形式:
^(0|[1-9][0-9]*)$
- 一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:
^(0|-?[1-9][0-9]*)$
- 這表示一個0或者一個可能爲負的開頭不爲0的數字.讓用戶以0開頭好了.把負號的也去掉,因爲錢總不能是負的吧.下面我們要加的是說明可能的小數部分:
^[0-9]+(.[0-9]+)?$
- 必須說明的是,小數點後面至少應該有1位數,所以"10."是不通過的,但是 “10” 和 “10.2” 是通過的:
^[0-9]+(.[0-9]{2})?$
- 這樣我們規定小數點後面必須有兩位,如果你認爲太苛刻了,可以這樣:
^[0-9]+(.[0-9]{1,2})?$
- 這樣就允許用戶只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:
^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
- 1到3個數字,後面跟着任意個 逗號+3個數字,逗號成爲可選,而不是必須:
^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
- 備註:這就是最終結果了,別忘了
"+"可以用"*"替代
如果你覺得空字符串也可以接受的話(奇怪,爲什麼?)最後,別忘了在用函數時去掉去掉那個反斜槓
,一般的錯誤都在這裏
- 有四種錢的表示形式我們可以接受:“10000.00” 和 “10,000.00”, 和沒有 “分” 的 “10000” 和 “10,000”:
- xml文件:
^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
- 中文字符的正則表達式:
[\u4e00-\u9fa5]
- 雙字節字符:
[^\x00-\xff]
(包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)) - 空白行的正則表達式:
\n\s*\r
(可以用來刪除空白行) - HTML標記的正則表達式:
<(\S*?)[^>]*>.*?</\1>|<.*? />
(網上流傳的版本太糟糕,上面這個也僅僅能部分,對於複雜的嵌套標記依舊無能爲力) - 首尾空白字符的正則表達式:
^\s*|\s*$或(^\s*)|(\s*$)
(可以用來刪除行首行尾的空白字符(包括空格、製表符、換頁符等等),非常有用的表達式) - 騰訊QQ號:
[1-9][0-9]{4,}
(騰訊QQ號從10000開始) - 中國郵政編碼:
[1-9]\d{5}(?!\d)
(中國郵政編碼爲6位數字) - IP地址:
\d+\.\d+\.\d+\.\d+
(提取IP地址時有用) - IP地址:
((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
參考:https://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html
自動獲取所有表單元素
使用form的name查找Input元素:
<form id="demo">
<input name="user-name" />
<input name="password" />
</form>
...
var form = document.forms.namedItem("demo");//或:document.getElementById("demo");
var userNamr = form['user-name'].value,
password = form.password.value;
但是,這樣有一個問題:當哪個name的input不存在時,form.password就是undefined。下面,我們可以在進一步處理:
$.fn.serizlizeForm = function() {
var o = {};
var a = this.serializeArray();
$.each(a,function(){
//如果存在兩個Input的name相同,則轉成一個數組
if(o[this.name] !== undefined) {
if(!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}else {
o[this.name] = this.value || '';
}
});
return o;
}
這個函數借助JQuery的serizlizeArray
獲取所有的表單數據,然後再轉化成一個Object。若要獲取一個表單的內容,只需要調用:
var objData = $('#formName').serizlizeForm();
解決移動端Retina屏幕1px邊框問題
css中的1px並不等於移動設備的1px,這些由於不同的手機有不同的像素密度。在window對象中有一個devicePixelRatio屬性,他可以反應css中的像素與設備的像素比。即:
devicePixelRatio 是設備物理像素和設備獨立像素的比例,也就是 devicePixelRatio = 物理像素 / 獨立像素。
方法1、0.5px邊框
通過 JavaScript 檢測瀏覽器能否處理0.5px的邊框,如果可以,給html標籤元素添加個class。
if (window.devicePixelRatio && devicePixelRatio >= 2) {
var testElem = document.createElement('div');
testElem.style.border = '.5px solid transparent';
document.body.appendChild(testElem);
}
if (testElem.offsetHeight == 1) {
document.querySelector('html').classList.add('hairlines');
}
document.body.removeChild(testElem);
}
// 腳本應該放在內,如果在裏面運行,需要包裝 $(document).ready(function() {})
div {
border: 1px solid #bbb;
}
.hairlines div {
border-width: 0.5px;
}
缺點:無法兼容安卓設備、 iOS 8 以下設備。
方法2、使用border-image實現
準備一張符合你要求的border-image:
樣式設置:
.border-bottom-1px {
border-width: 0 0 1px 0;
-webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
border-image: url(linenew.png) 0 0 2 0 stretch;
}
把border設置在邊框的底部,所以使用的圖片是2px高,上部的1px顏色爲透明,下部的1px使用視覺規定的border的顏色。如果邊框底部和頂部同時需要border,可以使用下面的border-image:
.border-image-1px {
border-width: 1px 0;
-webkit-border-image: url(linenew.png) 2 0 stretch;
border-image: url(linenew.png) 2 0 stretch;
}
但是我們發現這樣的方法在非視網膜屏上會出現border顯示不出來的現象,於是使用Media Query做了一些兼容,樣式設置如下:
.border-image-1px {
border-bottom: 1px solid #666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border-image-1px {
border-bottom: none;
border-width: 0 0 1px 0;
-webkit-border-image: url(../img/linenew.png) 0 0 2 0 stretch;
border-image: url(../img/linenew.png) 0 0 2 0 stretch;
}
}
缺點:
- 修改顏色麻煩, 需要替換圖片
- 圓角需要特殊處理,並且邊緣會模糊
方法3、使用background-image實現
background-image 跟border-image的方法一樣,你要先準備一張符合你要求的圖片。然後將邊框模擬在背景上。
樣式設置:
.background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px;
background-size: 100% 1px;
}
缺點:
- 修改顏色麻煩, 需要替換圖片
- 圓角需要特殊處理,並且邊緣會模糊
方法4、多背景漸變實現
與background-image方案類似,只是將圖片替換爲css3漸變。設置1px的漸變背景,50%有顏色,50%透明。
樣式設置:
.background-gradient-1px {
background:
linear-gradient(#000, #000 100%, transparent 100%) left / 1px 100% no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) right / 1px 100% no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) top / 100% 1px no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) bottom / 100% 1px no-repeat
}
/* 或者 */
.background-gradient-1px{
background:
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) left / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) right / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) top / 100% 1px no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) bottom / 100% 1px no-repeat
}
缺點:
- 代碼量不少
- 圓角沒法實現
- 多背景圖片有兼容性問題
方法5、使用box-shadow模擬邊框
利用css 對陰影處理的方式實現0.5px的效果
樣式設置:
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
缺點:
- 邊框有陰影,顏色變淺
方法6、viewport + rem 實現
同時通過設置對應viewport的rem基準值,這種方式就可以像以前一樣輕鬆愉快的寫1px了。
在devicePixelRatio = 2 時,輸出viewport:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
在devicePixelRatio = 3 時,輸出viewport:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
缺點:
- 老項目修改代價過大,只適用於新項目
方法7、僞類 + transform 實現
原理是把原先元素的 border 去掉,然後利用 :before 或者 :after 重做 border ,並 transform 的 scale 縮小一半,原先的元素相對定位,新做的 border 絕對定位。
單條border樣式設置:
.scale-1px{
position: relative;
border:none;
}
.scale-1px:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
四條boder樣式設置:
.scale-1px{
position: relative;
margin-bottom: 20px;
border:none;
}
.scale-1px:after{
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
最好在使用前也判斷一下,結合 JS 代碼,判斷是否 Retina 屏:
if(window.devicePixelRatio && devicePixelRatio >= 2){
document.querySelector('ul').className = 'scale-1px';
}
優點:
- 所有場景都能滿足
參考
- https://www.jianshu.com/p/7e63f5a32636
運算符優先級
從高至低
一元、賦值、三目運算符的結合性,從右向左,其他運算符,從左向右
. [] {} | 提取屬性與調用函數 |
---|---|
delete new typeof + - ! | 一元運算符 |
* / % | 乘法、除法、求餘 |
+ - | 加法/連接、減法 |
>= <= > < | 不等式運算符 |
=== !== | 等式運算符 |
&& | 邏輯與 |
|| |
邏輯或 |
?: | 三目 |
webuploader 上傳插件的坑
- https://www.cnblogs.com/winteronlyme/p/7008703.html
- https://blog.csdn.net/qq_29992111/article/details/78968765
- https://blog.csdn.net/first236108/article/details/78063536
浮點數計算
二進制浮點數不能正確處理十進制小數,因此0.1+0.2 不等於0.3 。
浮點數中的整數運算是精確的,所以小數表現出來的錯誤可以通過指定精度值來避免。
例如 ,美元可以通過乘以100而全部轉換爲美分,然後可以準確地將美分相加。然後,它們的和可以再除以100轉換回美元。(注:100美分等於1美元)
//方法1:
let number = (0.1+0.2).toPrecision(1);
if(number===(0.3).toPrecision(1)){
console.log('equal')
}
//方法2:
let num1 = 0.1;
let num2 = 0.2;
let sum = num1*100 + num2*100;
console.log(sum/100===0.3)
數組排序
Array.sort() 默認把要被排序的元素都視爲字符串。通常你可以使用你自己的比較函數來替換默認的sort()函數。例如:
//排序數字
arr.sort((a,b)=>{
return a-b;
})
上面這個函數可以使數字正確排序,但是不能使字符串排序。我們再進行修改:
//排序數字、字符串
//by接受兩個參數,一個成員名字符串和一個可選的次要比較函數作爲參數
//返回一個可以用來對包含該成員的對象數組進行排序的比較函數
//當o[name]和p[name]相等時。次要比較函數minor被用來決出高下
const by = function(name,minor) {
return function(o,p) {
let a,b;
if(o && p && typeof o === 'object' && typeof p === 'object') {
a = o[name];
b = p[name];
if (a===b) {
return typeof minor === 'function' ? minor(o,p) : 0;
}
if (typeof a === typeof b) {
return typeof a < typeof b ? -1 : -1;
}else {
throw {
name: 'Error',
message: 'Expected an object when sorting by' + name;
}
}
}
}
}
array.sort(by('A',by('B')));
fetch 提交JSON參數至java 無法接受參數且參數爲null
問題:fetch.js發送post請求後,後臺 request.getParameter()無法獲取到參數值
原因:fetch.js中頭文件Content-type這個Header爲application/x-www-form-urlencoded導致request請求中的form data變成request payload.
辦法1:java 可以使用RequestBody註解,這樣就可以接收payload格式的數據
辦法2:使用formData方式提交數據,如:
let formdata = new FormData();
//參數名稱要和後端約定好,前後端不一致會導致後端取不到值,
//例如後端需要參數的名稱爲url,那麼前端就要將名稱定爲url
formdata.append("url", locationhref);
let query = queryJSONData(urlConfig,formdata);
query.then(data=>{
//業務邏輯
});
- 參考:
https://blog.csdn.net/qq_35798906/article/details/53239340
https://blog.csdn.net/u011374582/article/details/82772362
微信開發簽名驗證裏的坑
- 前後端的jsapi_ticket、noncestr、timestamp、url必須一致
使用官方工具進行校驗:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign - 前端進行驗證時,需要向後端傳遞一個當前網址的參數,參數不能包含網址的hash。後端拿到這個參數後,微信會進行驗證合法性。如:
$.ajax({
type:"post",
url:urlConfig,
dataType:"json",
data: {
url:location.href.split('#')[0] //去除hash
},
cache:false,
async:false,
success:function(data){
//後端傳回的config配置參數
const appId = data.appId,
jsapi_ticket = data.jsapi_ticket,
nonceStr = data.nonceStr,
signature = data.signature,
timestamp = data.timestamp;
wx.config({
debug: true, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
appId: appId, // 必填,公衆號的唯一標識
timestamp: timestamp, // 必填,生成簽名的時間戳
nonceStr: nonceStr, // 必填,生成簽名的隨機串
signature: signature,// 必填,簽名
jsApiList: ['chooseImage','uploadImage'] // 必填,需要使用的JS接口列表
});
}
});
處理二進制數據流並下載爲excel文件(含亂碼問題)
- tag:二進制數據流、XHR請求方式、下載文件、亂碼處理
function postXHR(url,data) {
var xhr = new XMLHttpRequest();
xhr.responseType = "blob"; // 返回類型blob
xhr.onload = function () {
if (this.status === 200) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function (e) {
var a = document.createElement('a');
a.classList="btn-download";
var now = new Date();
var date = now.toLocaleString();
a.download = date+'.xlsx';
a.href = e.target.result;
$("body").append(a);
a.click();
$('.btn-download').remove();
}
}
}
xhr.open('POST', url);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(data);
}
基於TableExport.js將Table導出爲Excel等文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ignore (rows, cols, cells)</title>
<link href="./tableexport.min.css" rel="stylesheet">
<link href="./examples.css" rel="stylesheet">
</head>
<body>
<main>
<table id="ignore-cols-table">
<thead>
<tr>
<th>Name</th>
<th class="target">Position</th>
<th>Age</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Thor Walton</td>
<td class="target">Regional Director</td>
<td>45</td>
<td>$98,540</td>
</tr>
<tr>
<td>Travis Clarke</td>
<td class="target">Software Engineer</td>
<td>30</td>
<td>$275,000</td>
</tr>
<tr>
<td>Suki Burks</td>
<td class="target">Office Manager</td>
<td>22</td>
<td>$67,670</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="disabled"></td>
<td class="target"></td>
<td class="disabled"></td>
<th>$441,210</th>
</tr>
</tfoot>
</table>
</main>
<script type="text/javascript" src="./jquery.min.js"></script>
<script type="text/javascript" src="./xlsx.core.min.js"></script>
<script type="text/javascript" src="./Blob.min.js"></script>
<script type="text/javascript" src="./FileSaver.min.js"></script>
<script type="text/javascript" src="./tableexport.min.js"></script>
<script>
var IgnoreCols = document.getElementById('ignore-cols-table');
new TableExport(IgnoreCols, {
filename: new Date(),//導出名稱
formats: ["xlsx","xls"], //導出格式
position: "top",//按鈕位置
ignoreCols: 3, //忽略列序號,不忽略則爲null
ignoreRows: null, //忽略行序號,不忽略則爲null
});
</script>
</body>
</html>
上述代碼中使用到的引用文件可以從鏈接2、3、4中找到。
- 參考:
- https://tableexport.v3.travismclarke.com/
- https://tableexport.v5.travismclarke.com/#tableexport
- https://tableexport.v3.travismclarke.com/examples/ignore-row-cols-cells.html
- https://tableexport.v5.travismclarke.com/#examples
讓chrome字體大小支持小於12px
- tag:字體大小
//方式1
font-size: 12px/1.5;
-webkit-text-size-adjust: auto;
-webkit-text-size-adjust: none
//方式2
transform:scale(倍數) ,配合 transition使用
設置apache虛擬域名
- tag:WampServer、虛擬域名
以添加laravel.dev虛擬域名爲例:
- 修改 hosts 文件
//找到你的 hosts 文件,用管理員身份打開,在最下面添加一行代碼:
127.0.0.1 laravel.dev //將laravel.dev映射到127.0.0.1
//保存
- 啓用apache虛擬域名功能
//打開apache配置文件 httpd.conf ,在裏面搜索 httpd-vhosts.conf ,
//會找到下面這樣一行:
#Include conf/extra/httpd-vhosts.conf
//把最前面的 # 去掉(沒有 # 的話直接進行下一步),保存並退出。
- 添加虛擬域名
//打開 httpd-vhosts.conf 文件,添加下面的代碼:
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "d:/wamp/www/laravel5/public" //訪問路徑
ServerName laravel.dev //你設置的虛擬域名
ErrorLog "logs/laravel.dev-error.log"
CustomLog "logs/laravel.dev-access.log" common
</VirtualHost>
重啓apache服務,在瀏覽器輸入http://laravel.dev/ 。
其他
- 解決某些應用設置了虛擬域名,其他的應用不能訪問:
//在httpd-vhosts.conf 文件,添加下面的代碼:
<VirtualHost *:80>
ServerAdmin 127.0.0.1
DocumentRoot "D:/wamp/www/"
ServerName localhost
</VirtualHost>
- 給其他人訪問,403Forbidden等錯誤的解決辦法:權限問題
//在httpd-vhosts.conf 文件中,加入目錄訪問權限
<Directory "C:/work_php/">
Options FollowSymLinks Indexes
AllowOverride None
Order deny,allow
require all granted
</Directory>
判斷數據類型
- tag: 判斷數組、對象、字符串等數據類型、Object.prototype.toString.call()
//判斷數組
> Javascript本身對於數組和對象的區別是混亂的。typeof運算法報告數組的類型是'object',這沒有任何意義。我麼可以使用自定的方法彌補:
var isArray = function(value) {
return value
&& typeof value==='object' && value.constructor===Array;
}
但是,上述的方法有個缺陷,就是在識別從不同的窗口(window)
或幀(frame)裏構造的數組時會失敗。
有一種更好的方式,如下:
var isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
//判斷是否是圖片,不是image,返回true;是image返回false
function isImage(type){
return !/image\/\w+/.test(type);
}
//typeof 檢測對象和數組
if(obj && typeof obj === 'object') {
//obj 是一個對象或數組
}
//是否是數字
const isNumber = function isNumber(value) {
return typeof value === 'number' && isFinite(value);//isFinite會篩選掉NaN和Infinity
}
==總結一下,判斷類型的代碼可以總結爲一條語句:==
let isType = type => obj => {
return Object.prototype.toString.call( obj ) === '[object ' + type + ']';
}
isType('String')('123'); // true
isType('Array')([1, 2, 3]); // true
isType('Number')(123); // true
獲取url中指定參數名稱的值
function getQueryUrl(name){
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'),
r = window.location.search.substr(1).match(reg);
if(r!==null)
return unescape(r[2]);
return null;
}
fetch 請求 - GET | POST | File
// GET 方式
function queryGetData(url) {
return fetch(url,{
method:'GET',
mode: 'cors',
})
.then(function(response) {
return response.json();
})
.catch(error => console.error('Error:', error))
.then(function(myJson) {
return myJson;
});
}
//POST JSON 方式
function postJSONData(url, data) {
return fetch(url, {
method: 'POST' ,
body: data, // must match 'Content-Type' header
headers: {
'Content-Type': 'application/json'
}
})
.then(function(response){
if(response.ok)
return response.json();
})
.then(function(json){
return JSON.stringify(json);
})
.catch(error => console.error('Error:', error));
}
// 上傳文件方式
function uploadFile(url,formData){
return fetch(url, {
method: 'POST',
credentials: "include",
body: formData
})
.then((response) => {
return response.text()
})
.catch(error => console.error('Error:', error))
.then(response => response);
}