公司做网站/企拓客app骗局
浏览器的同源策略是为了保护用户的安全,限制了跨域请求。同源策略要求请求的域名、协议和端口必须完全一致,只要有一个不同就会被认为是跨域请求。
本文列举了一些处理跨域请求的解决方案:
- JSONP
- CORS跨域资源共享
- http proxy
- nginx反向代理
- webSocket 协议跨域
- postMessage
- document.domain + iframe
- window.name + iframe
- location.hash + iframe
1. JSONP
先说缺点,JSONP只能处理get请求。
script、iframe、img、link 等src属性,不存在跨域请求的限制。利用这个特性可以实现跨域请求
首先在服务器端用node+express模拟一个接口
let express = require("express");
let app = express();app.listen(8001, (_) => {console.log("服务器已启动!");
});app.get("/list", (req, res) => {// let { callback = Function.prototype } = req.query;let callback = req.query.callback;let data = {code: 200,messsage: "程序猿小野",};res.send(`${callback}(${JSON.stringify(data)})`);
});
1)使用jquery的ajax实现(axios的jsonp方法也可以)
$.ajax({url: "http://127.0.0.1:8001/list",method: "get",dataType: "jsonp", // => 执行的JSONP的请求,不加这一行会报跨域错误,has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.success: (res) => {console.log(res);},
});
web本地启动的服务器地址是:http://127.0.0.1:5501,服务器的地址是:http://127.0.0.1:8001/
不加dataType:"jsonp"时会报下面的跨域错误
2)利用 script标签的src属性
function handleResponse(data) {console.log("接收到的数据:", data);
}let scriptEle = document.createElement("script");
scriptEle.src = `http://127.0.0.1:8001/list?callback=handleResponse`;
document.head.appendChild(scriptEle);
成功接收到数据:
2. CORS跨域资源共享(必须掌握)
<script>axios.get("http://127.0.0.1:8001/list").then((res) => {console.log(res.data);}).catch((err) => {console.error(err);});
</script>
let express = require("express");
let app = express();app.listen(8001, (_) => {console.log("服务器已启动!");
});app.use((req, res, next) => {res.header("Access-Control-Allow-Origin", "http://127.0.0.1:5501");
// res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Credentials", "true"); // 后端允许发送Cookienext();
});app.get("/list", (req, res) => {let data = {code: 200,messsage: "程序猿小野",};res.send(`${JSON.stringify(data)}`);
});
3. http proxy (必须掌握)
这种情况是目前开发时,前端调试接口解决跨域问题,最常见的处理方法。一般通过webpack webpack-dev-server实现。用vue-cli创建的项目可以在vue.config.js中配置。
index.js
import axios from "axios";// axios.get("http://127.0.0.1:8001/user/list").then((res) => {
axios.get("/user/list").then((res) => {console.log(res);
});
没有配置proxy代理时,请求报错:
vue.config.js配置示例:
devServer: {open: true,port: 10003,headers: {"Access-Control-Allow-Origin": "*",},proxy: {"/": {target: "http://127.0.0.1:8001/",secure: false,changeOrigin: true,},},},
webpack.config.js 配置示例:
let path = require("path");
let HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {mode: "production",entry: "./src/index.js",output: {filename: "bundle.min.js",path: path.resolve(__dirname, "build")},devServer: {port: 3000,progress: true,contentBase: "./build",proxy: {"/": {target: "http://127.0.0.1:8001",changeOrigin: true},},},plugins: [new HtmlWebpackPlugin({template: "./src/index.html",filename: "index.html",})],
};
配置后请求成功:
4. nginx反向代理(必须掌握)
nginx 相关的内容比较多,有时间可以另开一个帖子去说。这里举一个我在实际开发过程中遇到的场景。我们的页面调其他前端模块的服务跨域了,在开发中没有,为什么上线后会出现呢。主要是因为开发时前端的服务都在同一个服务器上,不会产生跨域情况。上线部署在不同的服务器,这时候就出现了如下错误:
修改ngnix的相关配置,实际ip地址和对应的服务名已处理。修改后跨域问题解决:
upstream testxxx {server 127.0.0.1:3000 weight=1;server 127.0.0.2:4000 weight=1;
}location /fuwuming{proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://testxxx/fuwuming;
}
查看结果:
5. webSocket 协议跨域(必须掌握)
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。
原生WebSocket API使用起来不太方便,下面案例借助了socket.io.js的库,,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
前端代码:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div>user input:<input type="text" /><button id="button">发送</button></div><script src="./socket.io-4.7.2.js"></script><script>var socket = io("http://127.0.0.1:3000");// 与服务器连接成功socket.on("connect", () => {console.log("socket链接成功!" + socket.id);});// 接收服务器发送的消息socket.on("sendToClient", (message) => {console.log(message);});let sendToServerFunc = function () {let inputVal = document.getElementsByTagName("input")[0].value;// 向服务器发送消息socket.emit("sendToServer", {message: `我是客户端: ${inputVal}`,});};document.getElementsByTagName("input")[0].onblur = sendToServerFunc;document.getElementById("button").onclick = sendToServerFunc;</script></body>
</html>
node服务器代码:
// 导入express模块
const express = require('express')
// 引入http创建服务器实例的方法
const {createServer} = require('http')
const {Server} = require('socket.io')
// 创建express的服务器实例
const app = express()
// 创建http服务器实例
const httpServer = createServer(app)
// 创建socket.io的实例
const io = new Server(httpServer,{// 处理cors,解决跨域问题cors:{// origin: "http://127.0.0.1:5500",//需要跨域资源共享的地址origin: "http://127.0.0.1:5501",//需要跨域资源共享的地址allowedHeaders: ["my-custom-header"],credentials: true}
})
// 监听客户端连接,回调函数会传递本次连接的socket
io.on('connection',(socket) => {console.log(socket.id)// 监听到客户端发送的消息socket.on('sendToServer',(message) => {console.log(message)// 向客户端发送消息socket.emit('sendToClient',{message:'你好我是服务端,让我们来聊天呀'})})
} )// 调用listen方法,指定端口号并启动web服务器
httpServer.listen(3000,() =>{console.log('server is running at http://127.0.0.1:3000')
})
效果如下:
6. postMessage
MDN关于postMessage的介绍:
测试案列:
先用node启动两个服务器,不同端口,模拟跨域场景。
node serverA.js node serverB.js
let express = require("express");
let app = express();app.listen(1001, (_) => {console.log("服务器A已启动!");
});app.use(express.static("./"));
let express = require("express");
let app = express();app.listen(1002, (_) => {console.log("服务器B已启动!");
});app.use(express.static("./"));
A.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>A 页面</h1><iframe id="iframe" src="http://127.0.0.1:1002/B.html" frameborder="0" style="display: none;"></iframe><script>iframe.onload = function () {iframe.contentWindow.postMessage('这是A页面传过来的数据AAA', '*');}// 监听B页面传递的消息window.onmessage = function(res){console.log(res);}</script>
</body>
</html>
B.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><h1>B 页面</h1><script>// 监听A页面传递的消息window.onmessage = function (res) {console.log(res);res.source.postMessage("这是B页面传过来的数据BBB", res.origin);};</script></body>
</html>
下面几种方案只做了解,实际上几乎用不到。
7. document.domain + iframe (只做了解)
此方案只能实现:同一个主域,不同子域之间的操作
比如:http://www.domain.com/a.html 和 http://child.domain.com/b.html 属于同一个主域
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>document.domain = 'domain.com';var user = 'admin';
</script>
<script>document.domain = 'domain.com';// 获取父窗口中变量console.log(window.parent.user);
</script>
8. window.name + iframe(只做了解)
三个页面:A.html地址为:http://127.0.0.1:1001/A.html
B.html地址为:http://127.0.0.1:002/B.html
Proxy.html地址为:http://127.0.0.1:1002/proxy.html
可以看出B页面和Proxy页面同源,A想访问B的数据就跨域了
B.html的代码,可以看到B.html的window对象上有一个name属性
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>// 服务器端需要返回给A的信息都在window.name中存储window.name = "这是B页面的数据";</script></body>
</html>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><iframeid="iframe"src="http://127.0.0.1:1002/B.html"frameborder="0"style="display: none"></iframe><script>iframe.onload = function () {// 直接读不允许;console.log(iframe.contentWindow.name);};</script></body>
</html>
直接读不允许,控制报跨域错误
将iframe的src属性修改成和B.html同域的Proxy.html地址
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><iframeid="iframe"src="http://127.0.0.1:1002/B.html"frameborder="0"style="display: none"></iframe><script>let count = 0;iframe.onload = function () {// 直接读不允许;// console.log(iframe.contentWindow.name);// 需要我们先把地址重新指向到同源中,才可以// iframe.src = 'http://127.0.0.1:1001/proxy.html';// 只要proxy.html中的window没有name属性,那么这里就会取到B.html中window.name// console.log(iframe.contentWindow.name);if (count === 0) {iframe.src = "http://127.0.0.1:1001/proxy.html";count++;return;}console.log(iframe.contentWindow.name);};</script></body>
</html>
在A.html中成功读取到B.html的数据
9. location.hash + iframe(只做了解)
A和C同源,A和B非同源
A.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><iframeid="iframe"src="http://127.0.0.1:1002/B.html"frameborder="0"style="display: none"></iframe><script>let iframe = document.getElementById("iframe");iframe.onload = function () {iframe.src = "http://127.0.0.1:1002/B.html#msg=hello";};// 开放给同域C.html的回调方法function func(res) {console.log(res);}</script></body>
</html>
B.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><iframeid="iframe"src="http://127.0.0.1:1001/C.html"frameborder="0"style="display: none"></iframe><script>let iframe = document.getElementById("iframe");// 监听A传来的HASH值改变,再传给C.htmlwindow.onhashchange = function () {iframe.src = "http://127.0.0.1:1001/C.html" + location.hash;};</script></body>
</html>
C.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>// 监听B传来的Hash值window.onhashchange = function () {// 再通过操作同域A的js回调,将结果传回window.parent.parent.func(location.hash);};</script></body>
</html>
如果还有其他方案,欢迎留言补充。
总结一下:2、3、4、5 我个人觉得是必须要掌握的,因为我在实际的项目开发中都使用过。
相关文章:

跨域的多种方案详解
浏览器的同源策略是为了保护用户的安全,限制了跨域请求。同源策略要求请求的域名、协议和端口必须完全一致,只要有一个不同就会被认为是跨域请求。 本文列举了一些处理跨域请求的解决方案: JSONPCORS跨域资源共享http proxynginx反向代理web…...

Java / Scala - Trie 树简介与应用实现
目录 一.引言 二.Tire 树简介 1.树 Tree 2.二叉搜索树 Binary Search Tree 3.字典树 Trie Tree 3.1 基本概念 3.2 额外信息 3.3 结点实现 3.4 查找与存储 三.Trie 树应用 1.应用场景 2.Java / Scala 实现 2.1 Pom 依赖 2.2 关键词匹配 四.总结 一.引言 Trie 树…...

JS/jQuery 获取 HTTPRequest 请求标头?
场景:在jquery封装的ajax请求中,默认是异步请求。 需要定一个秘钥进行解密,所以只能存放在请求头中。然后需要值的时候去请求头中读取。 注意:dataType设置,根据请求参数的格式设置,如果是加密字符串&…...

Leetcode—2034.股票价格波动【中等】
2023每日刷题(五十二) Leetcode—2034.股票价格波动 算法思想 实现代码 class StockPrice { public:int last 0;multiset<int> total;unordered_map<int, int> m;StockPrice() {}void update(int timestamp, int price) {if(m.count(time…...

【Linux】diff命令使用
diff命令 是一个用于比较两个文件或目录之间差异的命令。它可以显示两个文件之间的行级别差异,并以易于阅读的格式输出结果。 著者 由保罗艾格特、迈克海特尔、大卫海耶斯、理查德史泰尔曼和Len Tower撰写。 diff命令 -Linux手册页 语法 diff [选项] [文件1]…...

讯飞星火认知大模型与软件测试结合,提升软件质量与效率
随着人工智能技术的不断发展,越来越多的企业开始将其应用于软件开发过程中。其中,讯飞星火认知大模型作为一种基于深度学习的自然语言处理技术,已经在语音识别、机器翻译、智能问答等领域取得了显著的成果。而在软件测试领域,讯飞…...

【Flink on k8s】- 4 - 在 Kubernetes 上运行容器
目录 1、准备 k8s 集群环境、Docker 环境 2、启用 kubernetes 2.1 查询 k8s 集群基本状态...

软件重装或系统重装后避免重复踩坑
1. Office软件的坑在于字体又没了 Word字体库默认没有仿宋_GB2312和楷体仿宋_GB2312,需要手动添加。 提供如下两个下载链接,亲测有效: 仿宋_GB2312 楷体_GB2312 安装步骤:解压-复制.ttf文件至C:\Windows\Fonts 持续更新贴~...

【Jmeter】JSON Extractor变量包含转义字符,使用Beanshell脚本来消除
如果使用Jmeter的JSON Extractor提取的变量包含特殊字符,直接引用时会包含转义字符。可以使用Beanshell脚本来进行字符串转换,从而消除这些转义字符。 import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONArray; import com.ali…...

GO设计模式——5、建造者模式(创建型)
目录 建造者模式(Builder Pattern) 建造者模式的核心角色 优缺点 使用场景 注意事项 代码实现 建造者模式(Builder Pattern) 建造者模式(Builder Pattern)是将一个复杂对象的构建与它的表示分离&…...

《LeetCode力扣练习》代码随想录——字符串(反转字符串II---Java)
《LeetCode力扣练习》代码随想录——字符串(反转字符串II—Java) 刷题思路来源于 代码随想录 541. 反转字符串 II 模拟过程 class Solution {public String reverseStr(String s, int k) {if(s.length()1){return s;}char[] chs.toCharArray();for(int i…...

WMMSE方法的使用笔记
标题很帅 原论文的描述WMMSE的简单应用 无线蜂窝通信系统的预编码设计问题中,经常提到用WMMSE方法设计多用户和速率最大化的预编码,其中最为关键的一步是将原和速率最大化问题转化为均方误差最小化问题,从而将问题由非凸变为关于三个新变量的…...

MySQL核心知识点整理大全1-笔记
目录 MySQL 一、MySQL的基本概念 1.数据库 2.表 3.列 4.行 5.主键 6.索引 二、MySQL的安装与配置 1.下载MySQL安装包 2.安装MySQL 3.启动MySQL 4.配置MySQL a.设置监听端口和IP地址 b.设置数据存储路径 c.设置字符集和排序规则 5.测试MySQL 三、MySQL的基本操…...

理解输出电压纹波和噪声:来源与抑制
医疗设备、测试测量仪器等很多应用对电源的纹波和噪声极其敏感。理解输出电压纹波和噪声的产生机制以及测量技术是优化改进电路性能的基础。 1:输出电压纹波 以Buck电路为例,由于寄生参数的影响,实际Buck电路的输出电压并非是稳定干净的直流…...

uni-app 微信小程序之好看的ui登录页面(二)
文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面(一) uni-app 微信小程序之好看的ui登录页面(二) uni-app 微信小程序之好看的ui登录页面(三) uni-app 微信小程…...

Textual Inversion
参考博客1:https://www.bilibili.com/read/cv25430752/...

笙默考试管理系统-MyExamTest----codemirror(47)
笙默考试管理系统-MyExamTest----codemirror(44) 目录 笙默考试管理系统-MyExamTest----codemirror(44) 一、 笙默考试管理系统-MyExamTest----codemirror 二、 笙默考试管理系统-MyExamTest----codemirror 三、 笙默考试…...

JVM中 Minor GC 和 Full GC 的区别
Java中的垃圾回收(Garbage Collection, GC)是自动内存管理的一部分,其主要职责是识别并清除程序中不再使用的对象来释放内存。Java虚拟机(JVM)在运行时进行垃圾回收,主要分为两种类型:Minor GC和…...

二十一章(网络通信)
计算机网络实现了多台计算机间的互联,使得它们彼此之间能够进行数据交流。网络应用程序就是在已连接的不同计算机上运行的程序,这些程序借助于网络协议,相互之间可以交换数据。编写网络应用程序前,首先必须明确所要使用的网络协议…...

[linux运维] 利用zabbix监控linux高危命令并发送告警(基于Zabbix 6)
之前写过一篇是基于zabbix 5.4的实现文章,但是不太详细,最近已经有两个小伙伴在zabbix 6上操作,发现触发器没有str函数,所以更新一下本文,基于zabbix 6 0x01 来看看效果 高危指令出发问题告警: 发出邮件告…...

手机升级到iOS15.8后无法在xcode(14.2)上真机调试
之前手机是iOS14.2的系统,在xcode上进行真机测试运行良好,因为想要使用Xcode的Instruments功能,今天将系统更新到了iOS15.8 ,结果崩了 说是Xcode和手机系统不兼容不能进行真机测试。在网上查了好些方法,靠谱的就是下载相关版本的…...

安装TensorFlow2.12.0
文章目录 一、安装Anaconda步骤 1: 下载Anaconda步骤 2: 运行安装程序步骤 3: 选择安装路径步骤 4: 完成安装步骤 5: 启动Anaconda Navigator步骤 6: 创建和管理环境二、安装TensorFlow(一)Anaconda修改国内镜像源(二)安装CPU版TensorFlow2.12.0(三)查看TensorFlow版本…...

elasticsearch 索引数据多了怎么办,如何调优,部署?
当Elasticsearch索引的数据量不断增加时,可以考虑以下调优和部署措施: 增加索引规模:Elasticsearch支持动态增加索引,可以根据数据量的增长情况逐步增加新的索引。同时,也可以考虑使用分片技术,将数据分散…...

人工智能企业引入S-SDLC,推动安全能力大跃升,保障AI技术体系深化落地
某人工智能公司是国际知名的上市企业,核心技术处于世界前沿水平。多年来,该企业在智慧教育、智慧医疗、智慧城市、智慧司法、金融科技、智能汽车、运营商、消费者等领域进行深度技术赋能,深入推进各个行业的智能化、数字化转型建设。 人工智能…...

Docker的数据卷
数据卷 1.数据卷概述 数据卷:容器与宿主机之间数据共享。 数据卷是一个供容器使用的特殊目录,位于容器中。 可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿…...

第二十一章总结博客
网络程序设计基础 局域网与互联网 为了实现两台计算机的通信,必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称,是一种网络协议。Internet 网络采用的协议是TCP/IP协议,其全称是Transmission …...

学习php中使用composer下载安装firebase/php-jwt 以及调用方法
学习php中使用composer下载安装firebase/php-jwt 以及调用方法 1、安装firebase/php-jwt2、封装jwt类 1、安装firebase/php-jwt composer require firebase/php-jwt安装好以后出现以下文件: 2、封装jwt类 根据所使用的php框架,在指定目录创建 Token.php <?ph…...

『TypeScript』深入理解变量声明、函数定义、类与接口及泛型
📣读完这篇文章里你能收获到 了解TypeScript变量声明与类型注解掌握TypeScript函数与方法的使用掌握TypeScript类与接口的使用掌握TypeScript泛型的应用 文章目录 一、变量声明与类型注解1. 变量声明2. 类型注解3. 类型推断 二、函数与方法定义1. 函数定义2. 方法定…...

如何优雅使用 vue-html2pdf 插件生成pdf报表
使用 vue-html2pdf 插件 业务背景,老板想要一份能征服客户的pdf报表,传统的pdf要手撕,企业中确实有点耗费时间,于是github上面看到开源的这个插件就…废话不多说,直接上教程 1.使用下面命令安装 vue-html2pdf npm i…...

C语言第十六集(前)
1.关于那个整形存储入char的 是先取好补码,再截断 例: 2.%u是以十进制的形式打印无符号整数 3.注意(背):存储的char类型变量的补码为10000000的直接解析为-128 4.signed char 类型的变量取值范围是-128~127 5.unsigned char 类型的变量取值范围是0~255 6.有符号类型的变量…...