第一部分  跨域及其相关知识

  什么是同源策略:指域名、协议、端口均相同,默认端口是80,二级域名也不是同源。

为了保证用户信息的安全,防止恶意的网站窃取数据。

   浏览器之间不能访问不同域名的cookie,提交表单的时候不受同源策略的限制,所以有跨站脚本攻击

  同源策略的限制对象(跨域)

  1)cookie、localStorage、IndexDB无法读取

  2)DOM无法获取

  3)  AJAX请求不能发送

  跨域的方法:

  1、设置同源策略(hosts)

  test.xxx.com  a.html

  <script>

    document.domain = 'example.com';  //设置同源策略

    document.cookie = 'text1=hello';

  </script>

  test2.xxx.com  b.html

  <script>

    可以取到cookie中的值

  </script>

 

  后台设置同源   domain = .example.com;

  注意这种方法只适用于cookie和iframe窗口,localStorage和IndexDB无法通过这种方式规避同源政策,而要使用PostMessage API。

  2、iframe通过下面三种方式实现跨域的信息传递

  a)片段识别符,即#号后面的内容,父窗口通过#后面的内容传递给子窗口信息

  父窗口代码:
  var src = originURL + '#' + data;

  document.getElementById('myIFrame').src = src;

  子窗口代码:

  window.onhashchange = checkMessage;

  function checkMessage(){

    var messaage = window.location.hash;

  }

  同样的,子窗口也可以改变父窗口的片段标识符。

  如果只改变片段标识符页面不会刷新。

  b)window.name

  window.name属性的特点无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性后,后一个网页可以读取它。

  这个方法感觉没什么用,要不然就是我没有理解,可以参考原文

http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

  c)window.postMessage

  跨文档通信API,这个是window对象新增的方法,允许跨窗口通信,无论两个窗口是否同源。

  var popup = window.open('http://bbb.com', 'title');

  popup.postMessage('Hello World!','http://bbb.com');

  postMessage方法的第一个参数是具体的信息内容,第二个参数是接收信息的窗口的源,即‘协议+域名+端口’,也可设为*,表示不限制域名,向所有窗口发送

 event.source:发送消息的窗口

  event.origin:消息发向的网址

  event.data: 消息内容。data的内容最新的浏览器可以接收任何格式的数据 

window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
  if (event.origin !== 'http://aaa.com') return;
  if (event.data === 'Hello World') {
      event.source.postMessage('Hello', event.origin);
  } else {
    console.log(event.data);
  }
}
window.onmessage = function(e){}
写法是上面这种形式,源页面打开其他域的页面,然后用获取的窗口变量postMessage,新打开的页面会收到发送的信息。
参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
postMessage要注意安全性,一定要指明来源和接收的格式。因为监听方法可以收到任何网页的信息
还可以通过postMessage来操作localStorage

加强版的子窗口接收消息的代码如下。


window.onmessage = function(e) {
  if (e.origin !== 'http://bbb.com') return;
  var payload = JSON.parse(e.data);
  switch (payload.method) {
    case 'set':
      localStorage.setItem(payload.key, JSON.stringify(payload.data));
      break;
    case 'get':
      var parent = window.parent;
      var data = localStorage.getItem(payload.key);
      parent.postMessage(data, 'http://aaa.com');
      break;
    case 'remove':
      localStorage.removeItem(payload.key);
      break;
  }
};

加强版的父窗口发送消息代码如下。


var win = document.getElementsByTagName('iframe')[0].contentWindow;
var obj = { name: 'Jack' };
// 存入对象
win.postMessage(JSON.stringify({key: 'storage', method: 'set', data: obj}), 'http://bbb.com');
// 读取对象
win.postMessage(JSON.stringify({key: 'storage', method: "get"}), "*");
window.onmessage = function(e) {
  if (e.origin != 'http://aaa.com') return;
  // "Jack"
  console.log(JSON.parse(e.data).name);
};
3、ajax实现跨域(除了可以使用代理服务器,如nginx,proxy)
a)jsonp(JSON with Padding
防护垫)
jsonp的原理是根据script src的跨域特性实现的,需要服务器配合,调用一个callback函数

首先,网页动态插入<script>元素,由它向跨源网址发出请求。


function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};

上面代码通过动态添加<script>元素,向服务器example.com发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。


foo({
  "ip": "8.8.8.8"
});

由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。

b)WebSocket

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。发送的头信息中有一个origin,服务器会根据这个源来判断是否是对的客户端。应用场景,数据实时变化的页面,如股票页面,聊天页面等。

参考文档:https://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html

c)CORS

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写,它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

它发出的也是XMLHttpRequest请求,它的内部机制是:

CORS需要浏览器和服务器同时支持,目前所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

 参考资料: http://www.ruanyifeng.com/blog/2016/04/cors.html

  

以上除了CORS是后台跨域设置,其他都是前端跨域,除此之外还有以下方式

  img  link(css 的攻击注入,background请求跨域)

  把代码压缩进图片(canvas)

 

小技巧:  

可以用img来测试网速,并作一些其他的处理,方式就是用

  var img = new img();

  img.src = '';   //1kb的图片

  var start = Date.now();

  img.onload = function(){

    var end = Date.now();

    var t = end - start;

  }

 

第二部分   html语义化,常用的语义化结构

常用的语义化结构:  

  <header>

    <nav></nav>  

  </header>

  <div class="content">

    <section></section>

    <section></section>

    <aside></aside>

    <ul></ul>

    <ol></ol>

    <p></p>

  </div>

  <footer></footer>

  这个目前用的少,语义化知道,但是基本没用,语义化的作用:

  a、去掉或样式丢失的时候能让页面呈现清晰的结构

  b、屏幕阅读器(如果访客有视障碍)完全会根据你的标记来“读”你的网页

  c、PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对css的支持较弱)

  d、搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重。搜索引擎是很重要的访客。你的页面是否对爬虫容易理解非常重要,因为爬虫很大程度上会忽略用于表现的标记,而只注重语义标记,SEO主要还是靠你网站的内容和外部链接的

  e、便于团队开发和维护,代码可读性较好

 

  html少写:减少dom渲染的时间,使用::before  ::after,来增加元素

  

  

 

posted on 2018-01-03 14:11  Phoebeli  阅读(358)  评论(0编辑  收藏  举报