JS跨域方法你知道哪些?

6 篇文章 4 订阅
2 篇文章 0 订阅

跨域

协议、域名、端口不同,需要跨域

跨域解决方案

jsonp:JSON with Padding

  • script标签没有同城限制
  • 服务端返回页面上callback包裹的json数据
  • 兼容性好
  • 仅支持GET

CORS:Cross-origin resource sharing 跨域资源共享

简单请求 :
满足以下 2 条件

  • GET HEAD POST
  • Content-Type
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

复杂请求:

不满足以上2条件

  • 需发送 OPTION 预检请求,查询服务器支持的方法
  • 按请求类别处理
const express = require('express')
  const app = express()
  const whiteList = ['http://localhost']
  app.use((req, res, next) => {
    const origin = req.headers.origin
    if (whiteList.includes(origin)) {
      // 允许访问源,附带凭证请求时,必须指定 URI。相反,可设置为 *
      res.setHeader('Access-Control-Allow-Origin', origin)
      // 允许请求头,逗号隔开
      res.setHeader('Access-Control-Allow-Headers', 'authorization, username')
      // 允许请求方法,逗号隔开
      res.setHeader('Access-Control-Allow-Methods''GET, HEAD, POST, OPTIONS')
      /* 允许凭证
         客户端需配置 const xhr = new XMLHttpRequest()
         xhr.withCredentials = true */
      res.setHeader('Access-Control-Allow-Credentials', true)
      // 预检请求的返回结果,允许请求头和请求方法可以被缓存多久,缓存期间不再发送预检请求,单位秒
      res.setHeader('Access-Control-Allow-Max-Age', 10)
      // 允许响应头
      res.setHeader('Access-Control-Expose-Headers', 'authorization, username')
      if (req.method === 'OPTIONS') {
        res.end() // 预检请求直接返回空响应体
      }
    }
  })

postMessage

  • window属性
  • 跨窗口,跨框架frame、iframe,跨域
  • 允许不同源脚本采用异步方式进行有限通信
 otherWindow.postMessage(message, targetOrigin, [transfer])
  // otherWindow:
  iframe.contentWindow 属性
  window.open 返回
  window.frames 访问
  window.onmessage = e => console.log(e.data) // 接收返回数据

Websocket

  • 基于 TCP
  • 全双工通信
  • 应用层协议
 // 客户端
  const socket = new WebSocket('ws://localhost:3000')
  socket.onopen = () => socket.send('message') // 向服务器发送数据
  soket.onmessage = e => console.log(e.data) // 接收服务器返回数据
  // server.js
  const express = require('express')
  const app = express()
  const ws = require('ws')
  const wss = new ws.Server({port: 3000})
  wss.on('connection', ws => {
    ws.on('message', data => console.log(data))
  })

代理服务器转发

  • 代理服务器设置 CORS 请求头字段

nginx

add_header

kangle

  • 回应控制,增加表,标记模块,add_header

nodejs

response.writeHead

  • 代理服务器向源服务器继续请求

nginx

七层 HTTP 代理:配置 http

http {
    server {
      listen 80;
      location / {
        proxy_pass http://127.0.0.1:3000
      }
    }
}
  • 四层 TCP 代理:配置 stream
 steam {
    upstream proxyServer {
      server 127.0.0.1:3000;
    }
    server {
      listen 80;
      proxy_pass proxyServer;
    }
  }

document.domain

  • 主域名相同,子域名不同
  • 设置值为 主域名

iframe

  • window.name
  • 不超过 2MB
  • 同一个iframe
  • 加载跨域页,跨域页设置 window.name
  • 加载同域页,读取 iframe.contentWindow.name

location.hash

  • 不会被 URL 编码
  • 加载跨域页,参数跟在 # 后。window.onhashchange 监听 hash 变化
  • 跨域页获取 location.hash,加载同域页,参数跟在 # 后
  • 同域页设置 window.parent.parent.location.hash = location.hash,将参数回传

初中级运维工程师(linux/shell)
虚拟化网络工程师
Web前端软件工程师

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值