跨域,指的是浏览器不能执行其余网站的脚本。它是由浏览器的同源策略形成的,是浏览器施加的安全限制。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]
复制代码