跨域常用解决方案

Mar 10, 2019 19:48 · 603 words · 2 minute read

什么是跨域?

同源策略:它是一种约定,即:协议(http 与 https)+域名(www.baidu.com 与 m.taobao.com)+端口号(8080 与 8081)三者相同

一个域名地址组成

avatar

限制内容有:
  • Ajax 请求发送后被浏览器拦截
  • cookie、LocalStorge 等存储型内容
  • DOM 节点
特例:三个标签允许跨域
  • <img src=''>
  • <link href=''>
  • <script src =''>

跨域常用解决方案

1.jsonp

利用<script>标签没有跨域限制的漏洞,

function Jsonp({ url, params, cb }) {
  return new Promise((resolve, reject) => {
    let script = document.createElement('script')
    window[cb] = function(data) {
      resolve(data)
      document.body.removeChild('script')
    }
    params = { ...params, cb }
    console.log(params) //{name:"coco", cb:"showName"}
    let arrs = []
    for (let key in params) {
      arrs.push(`${key}=${params[key]}`)
    }
    console.log(arrs) // ["name=coco", "cb=showName"]
    script.src = `${url}?${arrs.join('&')}`
    console.log(script)
    document.body.appendChild(script)
  })
}
Jsonp({
  url: 'http://localhost:8081/name',
  params: { name: 'coco' },
  cb: 'showName'
}).then(data => {
  console.log(data)
})

2.cors

cors 通信的关键是后端,只要后端实现了 cors,就实现了跨域

服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

let xhr = new XMLHttpRequest()
xhr.open('PUT', 'http://localhost:3000', true)
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status >= 200) {
      console.log(xhr.response)
    }
  }
}
xhr.send()

//server.js 简要配置
let express = require('express')
let app = express()
app.use((req, res, next) => {
  // 设置源可以访问
  res.setHeader('Access-Control-Allow-Origin', origin)
  // 允许携带哪个头访问
  res.setHeader('Access-Control-Allow-Headers', 'name')
  // 允许访问的方法
  res.setHeader('Access-Control-Allow-Methods', 'PUT')
  // 允许携带cookie
  res.setHeader('Access-Control-Allow-Credentials', true)
  // 预检的存活时间
  res.setHeader('Access-Control-Max-Age', 6)
})

3.document.domain +iframe 跨域

(仅适用主域相同, 子域不同的跨域应用场景)🌰 a.test.com 和 b.test.com

4.node 中间层

跨域是浏览器的同源策略的安全机制,服务器之间是不存在跨域的。

avatar

5.nginx 反向代理

配置一个中转服务器,安装 nginx, 配置 nginx.conf 即可。

// proxy服务器
server {
    listen       80;
    server_name  www.domain1.com;
    location / {
        proxy_pass   http://www.domain2.com:8080;  #反向代理
        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
        index  index.html index.htm;
    }
}

总结以上只列举常用的一些跨域方案,其它方法我们后续介绍。

tweet Share