跨域的十种方式
一. josnp 只支持 get 方法,原理是引入通过 src 引入 script
- 后端代码
//后端需要取到前端传递过来的回调函数名称和参数
app.get('/cors', function(req, res) {
let { cb, wd } = req.query;
res.send(`${cb}({data:"你好"})`);
});
- 前端代码
$.ajax({
url: 'http://localhost:3000/cors',
type: 'GET',
dataType: 'jsonp',
data: {
wd: '你好'
},
jsonp: 'cb',
success: function(data) {
console.log(data);
}
});
二. cors 跨域
跨域资源共享 cross-origin resoure sharing
需要后端配置才可以 可以支持所有方法
简单请求 直接允许 post 和 get 跨域
复杂请求发送的时候 会先发一个预检请求(先问服务器支持不支持发送请求的类型)
预检请求 => OPTIONS
三. postmessage+iframe 跨域
- data:顾名思义,是传递来的消息
- source:发送消息的窗口对象
- origin:发送消息窗口的源(协议+主机+端口号)
- 确保 a、b 页面能访问
- http://localhost:3000/a.html
- http://localhost:4000/b.html
<!-- 页面引入b页面 -->
<iframe
id="frame"
src="http://localhost:4000/b.html"
frameborder="0"
onload="load()"
></iframe>
<script>
load = () => {
let frame = document.getElementById('frame');
frame.contentWindow.postMessage('你是好人', 'http://localhost:4000');
window.onmessage = function(e) {
console.log(e.data);
};
};
//我是b页面
window.onmessage = function(e) {
console.log(e.data);
e.source.postMessage('你是坏人', e.origin);
};
</script>
四. docmument.domain 只适合使用在二级域名的情况
window hots 目录 c:\windows\system32\drivers\etc
mac 在 /etc/hosts 设置二级域名
hosts 文件设置
127.0.0.1 www.ry.com
127.0.0.1 vip.ry.com
127.0.0.1 svip.ry.com
//可以通过以下 3 个地址进行访问
http://www.ry.com:4000/b.html
http://vip.ry.com:4000/b.html
http://svip.ry.com:4000/b.html
qq.com 一级域名 vip.qq.com music.qq.com qq 的二级域名
<!-- 访问的页面http://vip.ry.com:3000/a.html http://svip.ry.com:4000/b.html -->
<!-- 1.a页面引入b页面 -->
<iframe
src="http://svip.ry.com:4000/b.html"
frameborder="0"
onload="load()"
id="frame"
></iframe>
//2. b页面设置全局变量和一级域名
<script>
document.domain = 'ry.com';
window.a = '你好';
</script>
//3. a页面设置一级域名并且在iframe
加载完成后调用load方法通过frame.contentWindow.a 拿到b页面的全局变量
<script>
document.domain = 'ry.com';
function load() {
console.log(frame.contentWindow.a);
}
</script>
五. websoket 双工协议
//file:///Users/ruanye/Desktop/cross-domain/5.websocket/index.html
//前端 一般用socket.io进行兼容
let socket = new WebSocket('ws:localhost:3000');
socket.onopen=function(){
socket.send('你好')
}
socket.onmessage=function(e){
console.log(e.data)
}
//后端 npm install ws
let express = require('express');
let app = express();
let Websocket =require('ws');
<!-- 创建websoket服务器 -->
let wss = new Websocket.Server({port:3000})
<!-- 创建连接和发送消息 -->
wss.on('connection',function(ws){
ws.on('message',function(data){
console.log(data)
ws.send('你也好')
})
})
六. webpack 代理
vue-cli 2.0
config/index.js
proxyTable: {
'/':{
target:'http://localhost:3000',
changeOrigin:true,
pathRewrite:{
'^/':'/'
}
}
}
config/dev.env.js
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
API_HOST:'/' // +需要加API_HOST
})
// vue-cli3.0在vue.config.js里面进行配置
devServer: {
proxy: 'http://localhost:3000'
}
七. node 中间层代理
//服务端访问服务端不存在跨域
// 接口端服务器代码(axios在node里面也可以使用)
app.get('/nodecors', function(req, res) {
res.send('1234');
});
//客户端代码 客户端在客户端的服务器里面用axios请求请求接口服务器
app.get('/a', async function(req, res) {
let data = await axios.get('http://localhost:3000/nodecors');
let result = data.data;
res.json(result);
});
八. window.name + iframe 跨域
//a页面、b页面 同一个域名 c页面自己一个域名
//a获取c的数据,a先引用c c把值放在window.name上,iframe加载完成后把a的引用地址改到b
// a页面 firame的window.name并没有改变
//firstload 防止死循环
let firstload = true;
function load(){
let frame= document.getElementById('frame');
if(firstload){
frame.src ='http://localhost:3000/b.html';
firstload = false;
}else{
console.log(frame.contentWindow.name)
}
//b页面
//c页面
window.name = '你好'
九. location.hash+ iframe
`有 a、b、c 三个页面 a、b 同域 c 是独立域
- a 页面通过 iframe 引入 c 页面,并且传入一个 hash 值 #name
- c 动态创建 ifame,iframe 的 src 是 b 页面,c 通过 ifrmae 把 hash 值传递给 b,把 ifram 添加到 dom 里面
- b 页面--> 父亲--> c 页面-->父亲-->a 页面
- c 页面可以通过 b 页面的 location.hash 拿到 c 传给 b 的 hash 值
- b 页面将拿到 hash 放到 a 的 hash 值中
- a 页面监听 hash 值改变事件能拿到 c 传过来 hash 值
let iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/b.html#youare';
document.body.appendChild(iframe);
//b 页面 放值
window.parent.parent.location.hash = location.hash;
//a页面监听
window.onhashchange = function() {
console.log(location.hash);
};
十. nginx 反向代理
- 需要 3 个端口 服务端 nginx 服务器 静态文件服务器
window conf 文件夹里面 找到 nginx.conf
- nignx 不能在任何中文目录里面
- mac 前往 /usr/local/etc/nginx
- http 里面 server 表示虚拟服务器器
- server_name www.ruanye.com
- ping 命令加域名 可以测试连接 `ping www.baidu.com`
- server
listen 80 监听端口号
server_name 虚拟服务器的名字
- nginx 命令
- nginx #启动
- 重新加载 nginx -s reload
- 退出 nginx -s quit
//配置跨域头
http {
###start####
// 允许什么域名进行跨域
add_header Access-Control-Allow-Origin *;
// 允许什么头进行跨域
add_header Access-Control-Allow-Headers X-Requested-With;
//允许什么方法进行跨域
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
###end ###
}
//配置代理的域名 proxy_pass 需要代理的域名
server {
listen 8080;
server_name www.ai.com;
location / {
proxy_pass http://localhost:3000;
root html;
index index.html index.htm;
}
http://localhost:8080/cors
npm install nodemon -g
node 有改动自动自动重启
10 声望
1 粉丝
推荐阅读
内置对象string的方法
在js中,String和Array是同级的,都是js中的内置对象。因此String也像Array那样有很多操作的方法。注意:String对象的涵盖范围,它包含所有的字符串。1. 字符串对象的属性length(1) 表示字符串的长度。(就是这个...
王影阅读 902
ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -> Preference-> Settings(如果装了中文插件包应该是 文件 -> 选项 -> 设置),搜索 eslint,点击 Edit in setting.json
谭光志赞 34阅读 20.7k评论 9
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...
chokcoco赞 22阅读 2.2k评论 3
你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...
XboxYan赞 23阅读 1.6k评论 1
在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...
边城赞 17阅读 2k
【代码鉴赏】简单优雅的JavaScript代码片段(一):异步控制
Promise.race不满足需求,因为如果有一个Promise率先reject,结果Promise也会立即reject;Promise.all也不满足需求,因为它会等待所有Promise,并且要求所有Promise都成功resolve。
csRyan赞 26阅读 3.3k评论 1
「彻底弄懂」this全面解析
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在 哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在 函数执行的过程中用到...
wuwhs赞 17阅读 2.4k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。