跨域/同源笔记

2019-05-07  本文已影响0人  fejavu

同源策略

浏览器出于安全考虑,只允许本域下接口交互,不同源的客户端脚本在没有明确授权下,不能读写对方的资源。

同源例子:
google.com/ai,google.com/bigdata

不同源例子:

跨域方法

JSONP

以 script 标签加载数据的方式绕过同源策略,后端返回数据时拼接函数,将返回数据作为拼接函数的参数,数据返回后执行该函数。

<script>
showData(string) {
  console.log(JSON.parse(string));
}
</script>
<script 
src="http://google.com/ai.js?callback = showData">
</script>

CORS

CORS,cross-origin resourse sharing,支持现在浏览器,IE10以上。

在后端加上这句话:

// allow all request of cross origin
res.setHeader('Access-Control-Allow-Origin','*');
// allow only the request of  'example.com:8080' 
res.setHeader('Access-Control-Allow-Origin','example.com:8080');

postMessage

iframe 域名和当前域名跨域。

$('.main input').addEventListener('input', function() {
  windows.parent.postMessage(this.value, '*');
})

window.addEventListener('message', function(e) {
  $('#input').value = e.data;
  console.log(e.data);
})

实践检验

在本地写一个html,地址是 http://localhost/index.html
,放置一个 button,点击后向http://127.0.0.1:80请求,此时两个文件不同域名,因此处于跨域,运用 CORS,cross-origin resourse sharing 方法,通过服务器端设置一个跨域允许,从而将服务器端数据返回到不同源请求。

html 客户端

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <button>show something</button>
  <script>
    function $(selector) {
      return document.querySelector(selector);
    }

    $('button').onclick = function() {
      console.log('clicked');
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'http://127.0.0.1:80/getst',true);
      xhr.send();
      xhr.onload = function(){
        var resP = document.createElement('p');
        resP.innerHTML = JSON.parse(xhr.responseText)
        $('body').appendChild(resP);
        // console.log(JSON.parse(xhr.responseText));
      }
    }
  </script>
</body>
</html>

server 端

var http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');

http.createServer(function(req, res) {
  var pathObj = url.parse(req.url,true);

  switch(pathObj.pathname) {
    case '/getst':
      var something = "This is a cross origin response via a request";
      res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
      res.end(JSON.stringify(something));
      break;
    default:
      fs.readFile(path.join(__dirname,pathObj.pathname), function(e,data){
        if(e){
          res.writeHead(404,'not found');
          res.end("<h1>404 Not Found</h1>");
        }else {
          res.end(data);
        }
      })
  }
}).listen(80);
请求成功示意

可以看到,请求的客户端域名是:localhost/index.html,而请求的地址是:http://127.0.0.1:80,两者是跨域的,而在服务器端设置

res.setHeader('Access-Control-Allow-Origin', 'http://localhost');

就是允许http://localhost进行跨域请求,因此请求成功。如果将这行去掉,这回造成非同源拦截:

非同源拦截
上一篇 下一篇

猜你喜欢

热点阅读