CSS
CSS垂直居中的8种方法
jQuery
closet
从当前元素开始,沿 DOM 树向上遍历,直到找到已应用选择器的一个匹配为止。返回包含零个或一个元素的 jQuery 对象
.closest(selector)
JS
冒泡排序
从小到大排序
/**
* 冒泡排序 从小到大排序
* @description 双重for循环 相邻元素两两对比,元素交换,大的元素交换到后面,进行第一次循环后最大的在最后面
* @method arrS2LSort
* @param {Array} arr 需要排序的数组
* @returns 返回排序后的数组
* @example arrS2LSort([4,2,3,5,1])=>[1,2,3,4,5]
*/
function arrS2LSort(arr) {
var len = arr.length;
for (var i = 0; i < len-1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
从大到小排序
/**
* 冒泡排序 从大到小排序
* @description 双重for循环 相邻元素两两对比,元素交换,小的元素交换到后面,进行第一次循环后最小的在最后面
* @method arrL2SSort
* @param {Array} arr 需要排序的数组
* @returns 返回排序后的数组
* @example arrL2SSort([4,2,3,5,1])=>第1层for 4次=>第1遍 第2层for 4 次=>[4,3,5,2,1]=>第2遍 第2层for 3 次=>[4,5,3,2,1]=>第3遍 第2层for 2 次=> [4,5,3,2,1]=>第4遍 第2层for 1 次=> [5,4,3,2,1]
*/
function arrL2SSort(arr) {
var len = arr.length;
for (var i = 0; i < len-1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
数组去重
方法1 双重for循环去重
/**
* 数组去重 方法1 双重for循环去重
* @description 即arr[1]与后面的所有比如有相同则删除那个元素,然后在拿arr[2]与后面的所有比
* @method arrDeduplication
* @param {Array} arr 需要去重的数组
* @returns 返回去重后的数组
* @example arrDeduplication1([1,2,2,2,3,3,4])
*/
function arrDeduplication1(arr){
// 第一层for 用来控制循环的次数 如 arr[1]=2
for(var i=0; i<arr.length; i++){
// 第二层for 用来控制与第一层比较的元素 如 arr[2]=3
for(var j=i+1; j<arr.length; j++){
// 比较arr[i]与arr[j] 如 arr[1]与arr[2] 如果相等
if(arr[i] == arr[j]){
arr.splice(j,1); // 从第j个位置上删除1 个元素 如删除索引为2的元素,此时arr为[1,2,2,3,3,4] 第一层for 再遍历时少了刚才重复的数据
j--;// 如j为2,执行后j为1,下次循环时j为2,此时比较arr[1]与arr[2](原始arr[3]),如果j不减1,则会漏掉一个进行比较的元素
}
}
}
return arr;
}
方法2 单层for循环与sort排序结合
/**
* 数组去重 方法2 单层for循环与sort排序结合
* @method arrDeduplication2
* @description 即左右相比较,相同删除左边,再拿左边(删除前的右边)与右边相比较
* @param {Array} arr 需要去重的数组
* @returns 返回去重后的数组
* @example arrDeduplication2([1,2,10,3,3,4])
*/
function arrDeduplication2(arr){
arr.sort();//sort排序是把元素当字符串排序 如[1,10,2,3,3,4]
for(var i = 0; i < arr.length-1;i++){
// 如arr[3]与arr[4]
if(arr[i]==arr[i+1]){
arr.splice(i,1);// 如[1,10,2,3,4]
i--;//如 2
}
}
return arr;
}
方法3 用一个空数组去存首次出现的元素
/**
* 数组去重 方法3 用一个空数组去存首次出现的元素
* @method arrDeduplication3
* @description
* @param {Array} arr 需要去重的数组
* @returns 返回去重后的数组
* @example arrDeduplication3([1,2,10,3,3,4])
*/
function arrDeduplication3(arr){
var newArr = [];
for(var i = 0; i < arr.length; i++){
if(newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i]);
}
}
return arr;
}
方法4 利用对象给首次出现的属性赋值并用一个空数组去存首次出现的元素
/**
* 数组去重 方法4 利用对象给首次出现的属性赋值并用一个空数组去存首次出现的元素
* @method arrDeduplication4
* @description
* @param {Array} arr 需要去重的数组
* @returns 返回去重后的数组
* @example arrDeduplication4([1,2,10,3,3,4])
*/
function arrDeduplication4(arr){
var obj = {};
var newArr = [];
for(var i = 0; i < arr.length; i++) {
if(obj[arr[i]] == undefined) {
newArr.push(arr[i]);
obj[arr[i]] = 1;
}
}
return newArr;
}
同源策略与跨域
同源策略
定义
如果两个URL的协议、域名和端口相同,则表示他们同源
URL的组成如下
- 协议
- 域名
- 端口
- 路径
限制
<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,不受同源限制- 浏览器限制了
JavaScript的权限使其不能读、写加载的内容。 - 只对网页的
HTML document文档做了限制,对加载的其他静态资源如javascript、css、图片等仍然认为属于同源。 - 从一个域上加载的脚本不允许访问另外一个域的文档属性
用途
阻止恶意网站注入页面并通过javascript脚本盗取重要信息(如用户名 密码)
跨域
Ajax跨域
Ajax (XMLHttpRequest)请求受到同源策略的限制。
Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外XMLHttpRequest是一个纯粹的Javascript对象,这样的交互过程,是在后台进行的,用户不易察觉。
因此,XMLHTTP实际上已经突破了原有的Javascript的安全限制。
JSONP
JSONP技术实际和Ajax没有关系。我们知道<script>标签可以加载跨域的javascript脚本,并且被加载的脚本和当前文档属于同一个域。因此在文档中可以调用/访问脚本中的数据和函数。如果javascript脚本中的数据是动态生成的,那么只要在文档中动态创建<script>标签就可以实现和服务端的数据交互。
JSONP就是利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。其中callback函数本地文档的JavaScript函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback函数。当这段脚本加载到本地文档时,callback函数就被调用。
//动态插入script标签
<script type="text/javascript">
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
</script>
JSONP协议封装了上述步骤,jQuery中统一是现在AJAX中(其中data type为JSONP):http://localhost:8080/test?callback=test_handler
为了支持JSONP协议,服务器端必须提供特别的支持[2],另外JSONP只支持GET请求。
Proxy
使用代理方式跨域更加直接,因为SOP的限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。 使用本方法跨域步骤如下:
- 把访问其它域的请求替换为本域的请求
- 本域的请求是服务器端的动态脚本负责转发实际的请求 各种服务器的Reverse Proxy功能都可以非常方便的实现请求的转发,如Apache httpd + mod_proxy。 Eg. 为了通过Ajax从http://localhost:8080访问http://localhost:8081/api,可以将请求发往http://localhost:8080/api。 然后利用Apache Web服务器的Reverse Proxy功能做如下配置: ProxyPass /api http://localhost:8081/api
CORS
Cross origin resource sharing
实现的基础是JavaScript不能够操作HTTP Header。
通过在HTTP Header中加入扩展字段,服务器在相应网页头部加入字段表示允许访问的domain和HTTP method
客户端检查自己的域是否在允许列表中,决定是否处理响应。
服务器端在HTTP的响应头中加入(页面层次的控制模式):
- Access-Control-Allow-Origin: example.com
- Access-Control-Request-Method: GET, POST
- Access-Control-Allow-Headers: Content-Type, Authorization, Accept, Range, Origin
- Access-Control-Expose-Headers: Content-Range
- Access-Control-Max-Age: 3600
多个域名之间用
逗号分隔,表示对所示域名提供跨域访问权限。*表示允许所有域名的跨域访问。
客户端可以有两种行为:
- 发送
OPTIONS请求,请求Access-Control信息。如果自己的域名在允许的访问列表中,则发送真正的请求,否则放弃请求发送。 - 直接发送请求,然后检查
response的Access-Control信息,如果自己的域名在允许的访问列表中,则读取response body,否则放弃。 本质上服务端的response内容已经到达本地,JavaScript决定是否要去读取。
Support: [Javascript Web Applications]
- IE >= 8 (需要安装caveat)
- Firefox >= 3
- Safari 完全支持
- Chrome 完全支持
- Opera 不支持
CORS协议提升了Ajax的跨域能力,但也增加了风险。一旦网站被注入脚本或XSS攻击,将非常方便的获取用户信息并悄悄传递出去。
Cookie 同源策略
Cookie中的同源只关注域名,忽略协议和端口。所以https://localhost:8080/和http://localhost:8081/的Cookie是共享的。
Flash/SilverLight跨域
浏览器的各种插件也存在跨域需求。通常是通过在服务器配置crossdomain.xml[2],设置本服务允许哪些域名的跨域访问。
客户端会首先请求此文件,如果发现自己的域名在访问列表里,就发起真正的请求,否则不发送请求。
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*"/>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
原型与原型链[3]
参考文章网址
- [1]同源策略和跨域访问
- [2]crossdomain.xml
- [3]原型与原型链