跨域的九种方案

同源策略

协议 域名 端口 三者都相同时满足: 同域

需要跨域:

cookie
LocalStorage
Dom(iframe)
ajax

跨域方案

jsonp

只能发送get请求,不支持post put delete

不安全 xss攻击

一般不采用了

代码实现:

<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}
    let arrs = [];
    for(let key in params) {
      arrs.push(`${key}=${params[key]}`);
    }
    script.src = `${url}?${arrs.join('&')}`;
    document.body.appendChild(script);
  });
}
jsonp({
  url: 'http://localhost:3000/say',
  params: {wd: 'how are you'},
  cb: 'show'
}).then(data => {
  console.log(data);
})
</script>

后端express:

安装依赖

npm install express

server.js代码

let express = require('express');
let app = express();

app.get('/say', function(req, res) {
  let {wd, cb} = req.query;
  console.log(wd);
  res.end(`${cb}('i am fine')`);
})
app.listen(3000);

cors

最常用,比较安全

前端ajax:

// get 请求
let xhr = new XMLHttpRequest;
xhr.open('GET', 'http://localhost:4000/getData', true);
xhr.setRequestHeader('name', 'i am iron man');
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4) {
    if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
      console.log(xhr.response);
    }
  }
}
// put 请求
let xhr = new XMLHttpRequest;
document.cookie = 'name=ironman';
xhr.withCredentials = true;
xhr.open('PUT', 'http://localhost:4000/getData', true);
xhr.setRequestHeader('name', 'i am iron man');
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4) {
    if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
      console.log(xhr.response);
      console.log(xhr.getResponseHeader('name')); // 需要后端设置允许 Expose-Headers
    }
  }
}
xhr.send();

后端express同上

// server1:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

// server2:
let express = require('express');
let app = express();
let whitList = ['http://localhost:3000']
app.use(function(req, res, next) {
  let origin = req.headers.origin;
  if(whitList.includes(origin)) {
    // 允许哪个源访问我
    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', 6000);
    // 允许前端获取哪个头
    res.setHeader('Access-Control-Expose-Headers', 'name');
    if(req.method === 'OPTIONS') {
      res.end(); // put请求时多发了一次测试请求,设置OPTIONS请求不做任何处理,不稳定
    }
  }
  next();
})
app.get('/getData', function(req, res) {
  res.end('i am fine');
})
app.put('/getData', function(req, res) {
  res,setHeader('name', 'captain');
  res.end('i am fine');
})
app.use(express.static(__dirname));
app.listen(4000);

postMessage

实现两个页面通信而不是数据通信

前端部分

<!-- server1 对应的页面a -->
<iframe id="frame" src="http://localhost:4000/b.html" frameborder="0" onload="load()">
</iframe>

<script>
function load() {
  let frame = document.getElementById('frame');
  frame.contentWindow.postMessage('how are you', 'http://localhost:4000');
  window.onmessage = function(e) {
    console.log(e.data);
  }
}
</script>
<!-- server2 对应的页面b -->
<script>
window.onmessage = function(e) {
  console.log(e.data);
  e.source.postMessage('i am fine', e.origin);
}
</script>

后端express同上

// server1:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

// server2:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(4000);

window.name

前端代码:

<!-- 页面a -->
<!-- a和b是同域的:3000
c是独立的:4000
a要获取c的数据
a先引用c c把值放到window.name,再把a引用的地址改到b -->

<iframe id="iframe" src="http://localhost:4000/c.html" frameborder="0" onload="load()">
</iframe>
<script>
let first = true;
function load() {
  if(first) {
    let iframe = document.getElementById('iframe');
    iframe.src = 'http://localhost:3000/b.html';
    first = false;
  } else {
    console.log(iframe.contentWindow.name);
  }
}
</script>

<!-- 页面c -->
<script>
window.name = 'i am fine'
</script>

后端express同上:

// server1:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

// server2:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(4000);

location.hash

路径后面的hash值可以用来通信

前端代码:

<!-- 页面设定同上,a访问c,a给c传一个hash值,c收到hash值之后,把hash值传递给b,b将结果放到a的hash值中 -->

<!-- 页面a -->
<iframe id="iframe" src="http://localhost:4000/c.html#howareyou" onload="load()">
</iframe>
<script>
window.onhashchange = function() {
  console.log(location.hash);
}
</script>

<!-- 页面c -->
<script>
console.log(location.hash);
let iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/b.html#iamfine';
document.body.appendChild(iframe);
</script>

<!-- 页面b -->
<script>
window.parent.parent.loaction.hash = location.hash;
</script>

后端同上:

// server1:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

// server2:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(4000);

document.domain

两个页面是一级域名和二级域名的关系

前端代码:

<!-- 页面a:http://a.ky1.cn:3000/a.html -->
<iframe id="frame" src="http://b.ky1.cn:3000/b.html" frameborder="0" onload="load()">
</iframe>

<script>
document.domain = 'ky1.cn';
function load() {
  console.log(frame.contentWindow.a);
}
</script>

<!-- 页面b -->
<script>
document.domain = 'ky1.cn';
var a = 100;
</script>

后端同上:

// server1:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

// server2:
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(4000);

nginx

nginx.org 下载安装

json文件夹新建文件 a.json

{
  "name": "跨域方案"
}

conf文件夹 nginx.conf文件

location ~.*\.json {
  root json;
  add_header "Access-Control-Allow-Origin" "*";
}

前端代码:

let xhr = new XMLHttpRequest;
xhr.open('get', 'http://localhost/a.json', true);
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4) {
    if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
      console.log(xhr.response);
    }
  }
}
xhr.send();

后端同上:

let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.listen(3000);

websocket

高级api 不兼容 一般使用socket.io

前端代码:

let socket = new WebSocket('ws://localhost:3000');
socket.onopen = function() {
  socket.send('how are you');
}
socket.onmessage = function(e) {
  console.log(e.data);
}

后端express同上:

// server:
// 安装依赖 npm install ws
let express = require('express');
let app = express();
let WebSocket = require('ws');
let wss = new WebSocket.Server({port:3000});
wss.on('connection', function(ws) {
  ws.on('message', function(data) {
    console.log(data);
    ws.send('i am fine');
  })
})

http-proxy

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值