一路繁花似锦绣前程
失败的越多,成功才越有价值

导航

 

1、浏览器的同源策略

* 两个URL的协议、主机、端口都相同的话,则这两个URL同源
* 浏览器的cookie、sessionStorage、localStorage、iframe、ajax都不支持跨域
* 跨域方案
    - jsonp
    - cors
    - postMessage
    - document.domain
    - window.name
    - location.hash
    - http-proxy
    - nginx
    - websocket

2、jsonp

* 原理
    - 浏览器的link、script、img支持跨域
    - 后端返回的是一段js脚本
* 缺点
    - 只能发送get请求,不支持post、put、delete
    - 跨站脚本攻击(xss),不安全
jsonpUtil({
  url: 'http://localhost:3000/world',
  params: {name: '发条'},
  cb: 'callback',
}).then(res => {
  console.log(res)
})

// 后端返回字符串:callback({name: '发条技师', age: 23})
function jsonpUtil({url, params, cb}) {
  return new Promise(resolve => {
    const scriptEl = document.createElement('script')
    params.cb = cb
    const paramsFormat = Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
    scriptEl.setAttribute('src', url + '?' + paramsFormat)
    document.head.appendChild(scriptEl)
    window[cb] = function (res) {
      document.head.removeChild(scriptEl)
      window[cb] = null
      resolve(res)
    }
  })
}

3、cors

const express = require('express')
const app = express()

app.use(function (req, res, next) {
  // 访问控制允许的源,*是通配符
  res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
  // 访问控制允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'Authorization')
  // 访问控制允许的请求方式
  res.setHeader('Access-Control-Allow-Methods', 'PUT')
  // 访问控制预检(OPTIONS请求)间隔(单位秒)
  res.setHeader('Access-Control-Max-Age', 60)
  // 访问控制允许cookie
  res.setHeader('Access-Control-Allow-Credentials', true)
  // 访问控制暴露的请求头
  res.setHeader('Access-Control-Expose-Headers', 'skill')
  next()
})

app.get('/world', function (req, res) {
  res.end(`callback({name: '冰霜巨龙', age: 28})`)
})
app.put('/hello', function (req, res) {
  console.log(req.headers.cookie)
  res.setHeader('skill', '300')
  res.end(`callback({name: '发条技师', age: 23})`)
})

app.listen(3000)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>前台页面</title>
  <script src="jquery.min.js"></script>
</head>
<body>
<script>
  document.cookie = 'hero=sv;path=/'
  $.ajax({
    url: 'http://localhost:3000/hello?cb=callback',
    type: 'PUT',
    headers: {
      Authorization: 'Bearer xxx',
    },
    xhrFields: {
      // 请求携带cookie
      withCredentials: true
    },
    success(data, textStatus, xhr) {
      console.log(xhr.getAllResponseHeaders())
    }
  })
</script>
</body>
</html>

4、postMessage

const express = require('express')
const path = require('path')
const app = express()

app.use(express.static(path.resolve(__dirname, '../static')))

app.listen(3000)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
</head>
<body>
<button onclick="handleClick()">a发送</button>
<iframe id="iframeElId" src="http://localhost:4000/b.html"></iframe>
<script>
  const iframeEl = document.getElementById('iframeElId')
  window.onmessage = function (ev) {
    console.log(ev.data)
  }

  function handleClick() {
    iframeEl.contentWindow.postMessage('白牛', 'http://localhost:4000')
  }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
</head>
<body>
<button onclick="handleClick()">b发送</button>
<script>
  let source = null
  window.onmessage = function (ev) {
    console.log(ev.data)
    source = ev.source;
  }

  function handleClick() {
    source.postMessage('小牛', '*')
  }
</script>
</body>
</html>

5、window.name

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
</head>
<body>
<!-- a和c不同域 -->
<iframe src="http://localhost:4000/c.html" onload="handleLoad(this)"></iframe>
<script>
  let first = true

  function handleLoad(self) {
    if (first) {
      // a和b同域
      self.setAttribute('src', 'http://localhost:3000/b.html')
      first = false
    } else {
      console.log(self.contentWindow.name)
    }
  }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>c</title>
</head>
<body>
<script>
  window.name = '敌法师'
</script>
</body>
</html>

6、location.hash

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
</head>
<body>
<!-- a和c不同域 -->
<iframe src="http://localhost:4000/c.html#pa"></iframe>
<script>
  window.onhashchange = function () {
    console.log(location.hash)
  }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
</head>
<body>
<script>
  // a和b同域
  window.parent.parent.location.hash = location.hash
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>c</title>
</head>
<body>
<script>
  console.log(location.hash)
  const iframeEl = document.createElement('iframe');
  iframeEl.setAttribute('src', 'http://localhost:3000/b.html#ug')
  document.body.appendChild(iframeEl)
</script>
</body>
</html>

7、document.domain

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
</head>
<body>
<!--
* hosts文件配置
    - 127.0.0.1 www.linjincheng.com
    - 127.0.0.1 blog.linjincheng.com
-->
<iframe src="http://blog.linjincheng.com:3000/b.html" onload="handleLoad(this)"></iframe>
<script>
  document.domain = 'linjincheng.com'

  function handleLoad(el) {
    console.log(el.contentWindow.info)
  }
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>b</title>
</head>
<body>
<script>
  document.domain = 'linjincheng.com'
  window.info = '屠夫'
</script>
</body>
</html>

8、websocket

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
</head>
<body>
<script>
  const socket = new WebSocket('ws://localhost:3000')
  socket.onopen = function () {
    socket.send('萨尔')
  }
  socket.onmessage = function (ev) {
    console.log(ev.data)
  }
</script>
</body>
</html>
const {WebSocketServer} = require('ws')
const wss = new WebSocketServer({port: 3000})
wss.on('connection', function (ws) {
  ws.on('message', function (data) {
    console.log(data.toString())
    ws.send('希尔瓦娜斯')
  })
})

9、nginx

http {
    server {
        location ~.*\.json {
            root   json;
            add_header "Access-Control-Allow-Origin" "*";
        }
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>a</title>
  <script src="jquery.min.js"></script>
</head>
<body>
<script>
  $.ajax({
    url: 'http://localhost:3000/info.json',
    success(data) {
      console.log(data)
    }
  })
</script>
</body>
</html>
posted on 2024-03-14 03:15  一路繁花似锦绣前程  阅读(14)  评论(0编辑  收藏  举报