跨域,指的是瀏覽器不能執行其餘網站的腳本。它是由瀏覽器的同源策略形成的,是瀏覽器施加的安全限制。javascript
- ——是瀏覽器安全策略
- ——協議名、域名、端口號必須徹底一致
- 舉例:
複製代碼
http://www.123.com/index.html 調用 http://www.123.com/server.php (非跨域)
http://www.123.com/index.html 調用 http://www.456.com/server.php (主域名不一樣:123/456,跨域)
http://abc.123.com/index.html 調用 http://def.123.com/server.php (子域名不一樣:abc/def,跨域)
http://www.123.com:8080/index.html 調用 http://www.123.com:8081/server.php (端口不一樣:8080/8081,跨域)
http://www.123.com/index.html 調用 https://www.123.com/server.php (協議不一樣:http/https,跨域)
請注意:localhost和127.0.0.1雖然都指向本機,但也屬於跨域。
瀏覽器執行javascript腳本時,會檢查這個腳本屬於哪一個頁面,若是不是同源頁面,就不會被執行
複製代碼
- 違背同源策略就會產生跨域
複製代碼
- jsonp cors websocket Node中間件代理(兩次跨域) ngix反向代理...
複製代碼
小提示:若是你回答跨域解決方案CORS,那麼面試官必定會問你實現CORS的響應頭信息Access-Control-Allow-Origin。
複製代碼
因此JSONP的原理其實就是利用引入script不限制源的特色,把處理函數名做爲參數傳入,而後返回執行語句,仔細閱讀如下代碼就能夠明白裏面的意思了。php
補充:1) JSONP和AJAX對比html
JSONP和AJAX相同,都是客戶端向服務器端發送請求,從服務器端獲取數據的方式。但AJAX屬於同源策略,JSONP屬於非同源策略(跨域請求)
複製代碼
2)JSONP優缺點vue
SONP優勢是簡單兼容性好,可用於解決主流瀏覽器的跨域數據訪問的問題。缺點是僅支持get方法具備侷限性,不安全可能會遭受XSS攻擊。
複製代碼
<script>
//建立 script 標籤
var script = document.createElement('script');
//設置回調函數
function getData(data) {
//數據請求回來被觸發的函數
console.log(data);
}
//設置script的src屬性,設置請求地址
script.src = 'http://localhost:3000?callback = getData';
//讓script生效
document.body.appendChild(script);
</script>
複製代碼
容許瀏覽器向跨域服務器發出XMLHttpRequest請求,從而克服跨域問題,它須要瀏覽器和服務器的同時支持。java
只要同時知足如下兩大條件,就屬於簡單請求node
條件1:使用下列方法之一:jquery
條件2:Content-Type 的值僅限於下列三者之一:ios
請求中的任意 XMLHttpRequestUpload 對象均沒有註冊任何事件監聽器; XMLHttpRequestUpload 對象可使用 XMLHttpRequest.upload 屬性訪問。nginx
Websocket是HTML5的一個持久化的協議,它實現了瀏覽器與服務器的全雙工通訊,同時也是跨域的一種解決方案。WebSocket和HTTP都是應用層協議,都基於 TCP 協議。可是 WebSocket 是一種雙向通訊協議,在創建鏈接以後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。 同時,WebSocket 在創建鏈接時須要藉助 HTTP 協議,鏈接創建好了以後 client 與 server 之間的雙向通訊就與 HTTP 無關了。 原生WebSocket API使用起來不太方便,咱們使用 Socket.io,它很好地封裝了webSocket接口,提供了更簡單、靈活的接口,也對不支持webSocket的瀏覽器提供了向下兼容。web
咱們先來看個例子:本地文件socket.html向 localhost:3000 發生數據和接受數據
// socket.html
<script>
let socket = new WebSocket('ws://localhost:3000');
socket.onopen = function () {
socket.send('我愛你');//向服務器發送數據
}
socket.onmessage = function (e) {
console.log(e.data);//接收服務器返回的數據
}
</script>
複製代碼
// server.js
let express = require('express');
let app = express();
let WebSocket = require('ws');//記得安裝ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
ws.on('message', function (data) {
console.log(data);
ws.send('我不愛你')
});
})
複製代碼
總結:CORS支持全部類型的HTTP請求,是跨域HTTP請求的根本解決方案 JSONP只支持GET請求,JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據。 不論是Node中間件代理仍是nginx反向代理,主要是經過同源策略對服務器不加限制。 平常工做中,用得比較多的跨域方案是cors和nginx反向代理
更多方法參考:juejin.im/post/5c2399…
<script>
axios.get('').then(function(){
}).catch(function(){
})
axios.post('').then(function(){
}).catch(function(){
})
</script>
複製代碼
在事件處理程序中調用 event.preventDefault() 或 event.stopPropagation() 是很是常見的需求。儘管咱們能夠在 methods 中輕鬆實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
爲了解決這個問題, Vue.js 爲 v-on 提供了 事件修飾符。經過由點(.)表示的指令後綴來調用修飾符。
<!-- 阻止單擊事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件再也不重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修飾符能夠串聯 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件偵聽器時使用事件捕獲模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只當事件在該元素自己(好比不是子元素)觸發時觸發回調 -->
<div v-on:click.self="doThat">...</div>
複製代碼
使用修飾符時,順序很重要;相應的代碼會以一樣的順序產生。所以,用 @click.prevent.self 會阻止全部的點擊,而 @click.self.prevent 只會阻止元素上的點擊。
console.log(typeof 1); // number
console.log(typeof 'a'); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof function fn(){}); // function
console.log(typeof {}); // object
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof new Error()); // object
複製代碼
tips:typeof 對於基本類型,除了 null 均可以顯示正確的類型;對於對象,除了函數都會顯示 object
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
function checkType() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]))
}
}
checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)
複製代碼
先判斷對象屬性的長度是否相等,再判斷每一個屬性的值是否相等
juejin.im/post/5c4169…
this 的指向取決於函數以哪一種方式調用:
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
複製代碼
箭頭函數實際上是沒有 this 的,這個函數中的 this 只取決於他外面的第一個不是箭頭函數的函數的 this。在這個例子中,由於調用 a 符合前面代碼中的第一個狀況,因此 this 是 window。而且 this 一旦綁定了上下文,就不會被任何代碼改變。
break;結束循環推薦使用
return 直接跳出方法,若是僅僅只想結束循環不建議使用,因其反作用是,這個方法再也不執行
循環變量=最大值/最小值(看你循環是從高數字到低仍是低到高,高到低設置成0,低到高設置成數組的length,該方法對for in語句無效)
//循環變量低到高
var arr=[1,2,3,4,5,6,7];
for(var i=0;i<arr.length;i++)
{
if(arr[i]==4)
{
//break; //方案1
//return; //方法後續代碼不執行 方案2
i=arr.length; //方案3
}
console.log(arr[i]); //1,2,3
}
複製代碼
//循環變量從高到低
var arr=[1,2,3,4,5,6,7];
for(var i=arr.length-1;i>-1;i--)
{
if(arr[i]==4)
{
//break; //方案1
//return; //方法後續代碼不執行 方案2
i=-1; //方案3
}
console.log(arr[i]); //7,6,5
}
複製代碼
//for in狀況
//循環變量從高到低
var arr=[1,2,3,4,5,6,7];
for(var i in arr)
{
if(arr[i]==4)
{
break;//方案1
//return;//方法後續代碼不執行 方案2
//方案3 對此不起做用
}
console.log(arr[i]); //1,2,3
}
複製代碼
var str = "jquery";
str = str.split(""); //字符串轉爲數組,["j","q","u","e","r","y"]
str = str.reverse(); //數組反轉, ["y","r","e","u","q","j"]
str = str.join(""); //數組轉字符串,"yreuqj"
複製代碼
* location.href //window.location.href ="https://www.xx.com/"
* location.replace //window.location.replace ="https://www.xx.com/"
複製代碼
var arr=[0,1,2,3,4,5,6,7,8,9]; //設置一個數組
console.log(arr.slice(2,7)); //2,3,4,5,6
console.log(arr.splice(2,7)); //2,3,4,5,6,7,8
//由此咱們簡單推測數量兩個函數參數的意義,
slice(start,end)第一個參數表示開始位置,第二個表示截取到的位置(不包含該位置)
splice(start,length)第一個參數開始位置,第二個參數截取長度
複製代碼
var x=y=[0,1,2,3,4,5,6,7,8,9]
console.log(x.slice(2,5)); //2,3,4
console.log(x); //[0,1,2,3,4,5,6,7,8,9]原數組並未改變
//接下來用一樣方式測試splice
console.log(y.splice(2,5)); //2,3,4,5,6
console.log(y); //[0,1,7,8,9]顯示原數組中的數值被剔除掉了
複製代碼
slice 和 splice雖然都是對於數組對象進行截取,可是兩者仍是存在明顯區別,函數參數上slice和splice第一個參數都是截取開始位置,slice第二個參數是截取的結束位置(不包含),而splice第二個參數(表示這個從開始位置截取的長度),slice不會對原數組產生變化,而splice會直接剔除原數組中的截取數據!
var obj = {a:'1',b:'2'}
obj.c = '3';
console.log(obj,'1'); //{a:'1',b:'2',c:'3'}
delete obj.a
console.log(obj,'2'); //{b:'2',c:'3'}
複製代碼
var mid = [3, 4];
var newarray = [1, 2, ...mid, 5, 6];
console.log(newarray); // [1, 2, 3, 4, 5, 6]
複製代碼