前端解决跨域问题

什么是跨域?

跨域是浏览器行为,是浏览器的一种安全策略;由于浏览器 同源策略 导致浏览器访问服务器时被拦截

同源策略(Sameoriginpolicy):
是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

这里还需要提一下http的url组成部分:

HTTP URL 由以下几个部分组成:

1,协议(Scheme):定义因特网服务的类型。最常见的是 http 和 https,分别用于普通和加密的 HTTP 服务。

2,主机(Host):服务器的域名系统 (DNS) 名称或 IP 地址。

3,端口(Port):可选,用于标识服务器上的特定网络程序;如果未指定,默认端口分别是 80 和 443 对应于 http 和 https。

4,路径(Path):服务器上的路径,标识特定资源或服务。

5,查询(Query):可选,发送到服务器的数据;以 ? 开始,可以包含键值对,用 & 分隔。

6,片段(Fragment):可选,用于指导浏览器跳转到页面的特定部分。

以下面地址为例

http://www.example.com:80/path/to/resource?key=value#section协议:http主机:www.example.com端口:80(默认)路径:/path/to/resource查询:key=value片段:section

如下表所示,协议,主机与端口导致的跨域例子

地址一地址二是否跨域跨域原因
https://www.baidu.comhttp://www.baidu.comhttps/http协议不同
https://www.baidu.comhttps://www.example.com主机不同
https://www.baidu.comhttps://www.baidu.com:80端口不同,https默认端口是443,http默认端口是80
https://www.baidu.comhttps://www.baidu.com:443端口一致

需要注意的是:跨域不一定都会有跨域问题。

因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是与当前页域名相同的路径,这能有效的阻止跨站攻击。
因此:跨域问题 是针对ajax的一种限制。
但是这却给我们的开发带来了不便,而且在实际生产环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同,怎么办?

解决跨域问题的方法

1,jsonp解决跨域

JSONP(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

原理:

html中的src(获取图片),的href(获取css),

实现封装jsonp的代码:

function jsonp({ url, params, callback }) {return new Promise((resolve, reject) => {let script = document.createElement("script");// 定义一个全局回调函数,若请求返回,则执行里边内容window[callback] = function(data) {resolve(data);document.body.removeChild(script);}let arrs = [];params = { ...params, callback };for (let key in params) {arrs.push(params[key]);}script.src = `${url}?${arrs.join("&")}`;document.body.appendChild(script);});
}jsonp({url: "http://localhost:3000/say",params: { wd: "Iloveyou" },callback: "show"
}).then(data => {console.log(data);
});

我们也可以直接在html中使用script标签

html前端代码

<script src="http://localhost:3000/getData?callback=func"><script><script>function func(res) {alert(res.message + res.name + "你永远" + res.age + "岁");}</script>

服务端代码:

router.get('/getData', (req, res) => {let data = {message: 'success!',name: '胡不说',age: 18}data = JSON.stringify(data)res.end('func(' + data + ')');
});

jsonp的优缺点

优点缺点
1,不受同源策略限制,实现跨域;
2,使用简单,不需要配置代理
3,兼容性好,低版本ie也能兼容,基本不存在兼容性问题
1,只支持get请求
2,jsonp在调用失败的时候不会返回各种HTTP状态码
3,跳过了同源策略,安全性没办法保证

2,cors头设置

这个一般情况跟前端没啥关系,需要后端去配置放开跨域白名单。

前端发现跨域了

具体沟通情况可参照如下:


前端:后端大大,我这边调您接口好像跨域了,我需要怎么做才能解决这个问题呢?后端:我现在好忙,你看看能不能自己解决一下前端:是这样的,我这边配置代理挺麻烦的,不过我先尝试一下(配置不配置再说,复不复杂再说,晚点再沟通)过了一会。。。前端:后端大大,我没解决后端:哦,那我来吧

node设置白名单解决跨域

const http = require('http')
const url = require('url')
// 创建server
const server = http.createServer()
// 定义跨域访问白名单
const authOrigin = ['http://127.0.0.1:5500']// 监听http请求
server.on('request', (req, res) => {const user = { // 模拟返回数据id: 1, name: 'zhangsan',age: 12}const origin = req.headers.originif(authOrigin.includes(origin)) {// 添加响应头,实现corsres.setHeader('Access-Control-Allow-Origin', '*') // 允许所有的地址跨域访问//res.setHeader('Access-Control-Allow-Origin', origin) // 只有白名单中的地址才可以跨域访问}res.end(JSON.stringify(user))
})// 设置监听端口
server.listen(8081, function() {console.log('server is running on 8081 port!')
})

java设置白名单解决跨域

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Beanpublic WebMvcConfigurer corsConfigurer() {return new WebMvcConfigurer() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允许跨域的路径.allowedOrigins("*") // 允许跨域请求的域名.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法.allowedHeaders("*") // 允许的请求头.allowCredentials(true); // 是否允许证书(cookies)}};}
}

3,代理服务器(Proxy Server)

同源策略是浏览器行为,那我们通过代理服务器访问就不受同源策略的限制了啊,不管是proxy还是nginx代理都是通过这个原理解决的跨域问题

我们以vue3 vite构建项目为例:

1,在项目根目录中的 vite.config.js 文件中,配置代理服务器:

import { defineConfig } from 'vite';export default defineConfig({server: {proxy: {'/api': {target: 'http://target-domain.com', // 目标服务器地址changeOrigin: true, // 是否改变源地址rewrite: (path) => path.replace(/^\/api/, '') // 重写路径}}}
});

2,在发送请求时,使用配置好的代理路径(例如 /api):

import axios from 'axios';axios.get('/api/some-endpoint').then(response => {console.log(response.data);
});

这样,所有发往 /api 的请求都会被代理到 http://target-domain.com,从而绕过同源策略,实现跨域通信。

4,Websocket

Websocket 是 HTML5 的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。

然后,不会有人用这个方法解决跨域的,Websocket实时通讯有它自己的使用场景,我们需要知道的就是它没有跨域问题就足够了

5,利用iframe标签

这个与jsonp类似,html的iframe标签不受同源策略影响,可以通过它解决跨域;了解有这个方法就行,除非特殊场景,一般也不会用它

总结一下

1,jsonp
2,cors头设置
3,搭建代理服务器
4,Websocket
5,利用iframe标签

整理知识点,基础不牢,地动山摇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51.网络游戏逆向分析与漏洞攻防-角色管理功能通信分析-角色选择的模拟与截取

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&…

制造业、能源等传统行业进行数字化转型时要注意哪些问题?

制造业、能源等传统行业在进行数字化转型时需要注意以下几个关键问题&#xff1a; 1、明确转型目标和战略规划&#xff1a;企业需要根据自身的业务特点、市场需求和长远发展目标&#xff0c;制定清晰的数字化转型战略。包括确定转型的重点领域、预期成果、时间表和资源投入。 …

阿里云云效CI/CD配置

1.NODEJS项目流水线配置(vue举例) nodejs构建配置 官方教程 注意:下图的dist是vue项目打包目录名称,根据实际名称配置 # input your command here cnpm cache clean --force cnpm install cnpm run build 主机部署配置 rm -rf /home/vipcardmall/frontend/ mkdir -p /home/…

计算分数和-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第48讲。 计算分数和&#…

java并发体系-锁

ReentrantLock ReentrantLock是Java并发编程中的一种锁机制。它的基本流程如下&#xff1a; 创建ReentrantLock对象。在需要加锁的代码块前调用lock()方法&#xff0c;该方法会尝试获取锁&#xff0c;如果锁已被其他线程占用&#xff0c;则当前线程会被阻塞。执行需要加锁的代…

redis架构知识点

Redis 在规模如下&#xff1a; 机器内存总量约70TB&#xff0c;实际使用内存约40TB&#xff1b;平均每秒处理约1500万次请求&#xff0c;峰值每秒约2000万次请求&#xff1b;每天处理约1万亿余次请求&#xff1b;单集群每秒处理最高每秒约400万次请求&#xff1b;集群实例与单机…

3 突破编程_前端_SVG(rect 矩形)

1 rect 元素的基本属性和用法 在SVG中&#xff0c;<rect> 元素用于创建矩形。 <rect> 元素有一些基本的属性&#xff0c;可以用来定义矩形的形状、位置、颜色等。以下是这些属性的详细解释&#xff1a; x 和 y &#xff1a;这两个属性定义矩形左上角的位置。 x …

[dvwa] sql injection(Blind)

blind 0x01 low 1’ and length(version()) 6 # syntax: substr(string , from<start from 1>, cut length) 1’ and substr(version(),1,1) ‘5’ # 1’ and substr(version(),2,1) ‘.’ # 1’ and substr(version(),3,1) ‘7’ # 1’ and substr(version(),4,…

leetcode 322

leetcode 322 题目 例子 思路 记忆化搜索&#xff0c;使用数组&#xff0c;记录val的最少硬币数量&#xff1b; 递归加bfs; 代码实现 #include <vector> #include <climits> // For INT_MAX #include <algorithm> // For minclass Solution { public:int…

C#下Httpclient post请求获取令牌

1.postman测试ok 2.C#代码 public static async Task<string> testGetToken(string URL, string param){string responseBody "eee";//using (var clientHandler new HttpClientHandler()){ var handler new HttpClientHandler();handler.ServerCertificat…

响应实践!赛宁网安亮相第二届全国先进技术成果转化大会

4月8日&#xff0c;第二届全国先进技术成果转化大会&#xff08;以下简称“大会”&#xff09;在苏州隆重举行。大会由江苏省国防科学技术工业办公室、苏州市人民政府、先进技术成果长三角转化中心主办。赛宁网安作为全球一流数字孪生靶场服务商&#xff0c;携数字孪生靶场、网…

软件测试面试准备—综合面

技术面试过了之后&#xff0c;HR约综合面&#xff0c;其实面之前我不太确定是不是HR面&#xff0c;以及会有哪些人&#xff0c;所以还是整理了下问题。有些问题附上答案&#xff0c;有些问题需要结合自己的工作场景来发挥。我参与的这家公司的综合面是HR来面的&#xff0c;其实…

python学习——re库的常用函数

参考资料&#xff1a;python网络爬虫技术与应用【邓维】 1、match() 从字符串头部开始匹配字符。 import re content"The123456ismyonephonenumber." # 字符串长度 print(len(content)) # 使用match匹配&#xff0c;第一个参数为正则表达式&#xff0c;第二个参数…

未来驾驶的革命:自动驾驶技术与智能交通系统的崛起

虽然自动驾驶技术和智能交通系统的开发似乎是资本密集型且技术要求高的领域&#xff0c;主要由大型企业主导&#xff0c;但普通创业者仍有机会从多个角度切入这一领域。以下是一些创业机会的思路&#xff1a; 1. 软件解决方案和应用开发 数据分析和处理工具 在自动驾驶技术领域…

element-ui的按需引入报错解决:MoudleBuildFailed,完整引入和按需引入

官网&#xff1a; Element - The worlds most popular Vue UI framework 1.完整引入 &#xff08;1&#xff09;下载&#xff1a; npm i element-ui -S &#xff08;2&#xff09;引入&#xff1a; 在 main.js 中写入以下内容&#xff1a; import Vue from vue; impor…

MLT媒体程序框架02:源码剖析

以MLT自带的Melt命令行工具源码为例 去掉一些不重要的代码 melt.c int main(int argc, char **argv) {int i;mlt_consumer consumer NULL;FILE *store NULL;char *name NULL;mlt_profile profile NULL;int is_progress 0;int is_silent 0;int is_abort 0;int is_getc …

javascript中创建变量的方式 与 var和let有什么区别

一、创建变量的7种方式&#xff1a; 1、var 2、function 创建变量&#xff08;函数名是一个变量 3、let 4、const 创建常量 5、import 基于es6 的模块规范导出需要的信息 6、class 基于 es6 创建的类 7、Symbol 创建唯一值 二…

Linux进阶篇:centos7扩展root分区:LVM应用案例

centos7扩展root分区&#xff1a;LVM应用案例 当服务器根分区或者是root分区存储空间快用完的时候&#xff0c;并且重要的数据都在root分区下&#xff0c;当如何应对&#xff0c;没关系坐好&#xff0c;分分钟解决它&#xff0c;我们可以进行分区扩容。 一 添加一块新的硬盘 …

谈谈系列之移动时代,我的产品技术观

其实一直想着写这篇文章&#xff0c;但是缺乏灵感&#xff0c;下笔犯难。信息时代发展速度快到令人目不暇接&#xff0c;从最开始的个人PC&#xff0c;到拨号上网&#xff0c;再到光纤入户&#xff0c;再到现在4G/5G移动互联网&#xff0c;一晃也不过短短三四十年。程序主流语言…

java 读取zip文件的两种方式

以下是使用Java读取zip文件的两种实现方法&#xff1a; 方法1&#xff1a;使用java.util.zip.ZipInputStream类 import java.io.FileInputStream; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;public class ZipReader …