什么是浏览器同源策略?如何处理同源策略带来的跨域问题?

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

什么是浏览器同源策略

浏览器的同源策略(Same-Origin Policy)是一种安全机制,用于限制一个网页文档或脚本如何与来自不同源的资源进行交互。同源是指两个 URL 的协议、主机和端口号都相同。

同源策略的目的是保护用户的隐私和安全。它可以防止恶意网站通过脚本访问其他网站的敏感信息或进行恶意操作。同源策略主要限制以下几个方面的交互:

  1. 跨域资源读取:在浏览器中,一个网页只能通过 AJAX、WebSocket 或 Fetch API 等方式来请求同源网站的数据。这意味着脚本无法直接读取来自其他域的数据,以防止恶意网站获取用户的敏感信息。

  2. 跨域资源加载:浏览器中的脚本无法直接加载来自其他域的资源,如 JavaScript 文件、CSS 文件或字体文件。这是为了防止恶意脚本篡改其他域的资源或执行恶意代码。

  3. 跨域窗口通信:浏览器中的脚本只能与同源窗口进行通信,不能直接操作或获取来自其他域的窗口对象的内容。

同源策略通过限制不同源之间的交互,提高了浏览器的安全性。然而,有时需要在不同源之间进行数据交换,为此引入了一些跨域解决方案,如跨域资源共享(CORS)和跨文档消息传递(PostMessage)。这些解决方案允许在特定条件下进行跨域交互,同时保持了一定的安全性。

如何解决跨域问题

跨域问题是由浏览器的同源策略所引起的,它限制了不同源(协议、域名、端口)之间的资源交互。要解决跨域问题,可以采取以下几种方法:

  1. JSONP(JSON with Padding):JSONP是一种利用<script>标签不受同源策略限制的特性来实现跨域请求的方法。通过在请求URL中添加一个回调函数参数,服务器返回的响应将被包裹在该函数中,从而实现跨域数据的获取。不过用的少。
    下面是一个简单的示例,演示如何使用 JSONP 进行跨域数据获取:

假设网页位于 http://www.example.com,希望从跨域的服务器 http://api.example.com 获取数据。

  1. 在客户端的 HTML 页面中添加以下代码:
<!DOCTYPE html>
<html>
<head><title>JSONP Example</title><script>function handleResponse(data) {console.log(data); // 在控制台中打印获取到的数据}</script>
</head>
<body><script src="http://api.example.com/data?callback=handleResponse"></script>
</body>
</html>

在这个例子中,在页面中定义了一个名为 handleResponse 的函数来处理获取到的数据。然后通过添加 <script> 标签来请求跨域服务器上的数据,并在 URL 的查询参数中指定回调函数的名称为 handleResponse

  1. 在跨域服务器 http://api.example.com 上,根据请求的 URL 参数返回相应的数据。服务器端代码可以是以下示例(使用 Node.js 和 Express 框架):
const express = require('express');
const app = express();app.get('/data', (req, res) => {const data = { message: 'Hello, World!' };const callbackName = req.query.callback; // 获取回调函数名称// 返回数据,并将数据包裹在回调函数中res.send(`${callbackName}(${JSON.stringify(data)})`);
});app.listen(80, () => {console.log('Server started');
});

在这个例子中,当客户端发起 GET 请求到 /data 路由时,服务器获取回调函数的名称,然后将数据包裹在回调函数中作为响应返回给客户端。

通过这种方式,客户端就能够从跨域服务器上获取数据,并在指定的回调函数中进行处理。
例子仅供参考

  1. CORS(Cross-Origin Resource Sharing):CORS是一种在服务器端配置的解决方案。通过在响应头中添加特定的跨域策略信息,允许浏览器在跨域请求时获取和处理来自其他域的数据。服务器需要设置适当的Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers等响应头来指定允许的跨域访问规则。
    以下是一个示例,演示如何使用CORS来允许跨域访问:
    假设网页位于 http://www.example.com,希望从跨域的服务器 http://api.example.com 获取数据。

  2. 在服务器端配置允许跨域访问的规则。具体的配置方式取决于服务器端的语言和框架。以下示例是使用 Node.js 和 Express 框架来配置CORS。

const express = require('express');
const app = express();// 配置CORS中间件
app.use(function(req, res, next) {// 允许特定域的跨域访问res.header('Access-Control-Allow-Origin', 'http://www.example.com');// 允许发送跨域请求的HTTP方法res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');// 允许的请求头res.header('Access-Control-Allow-Headers', 'Content-Type');// 是否允许发送Cookieres.header('Access-Control-Allow-Credentials', 'true');next();
});// 跨域请求处理
app.get('/data', (req, res) => {const data = { message: 'Hello, World!' };res.send(data);
});app.listen(80, () => {console.log('Server started');
});

在这个例子中,使用了 Express 框架,并在服务器端配置了一个中间件来处理CORS。在中间件中,我们设置了允许跨域访问的源(http://www.example.com)、允许的HTTP方法(GET、POST、PUT、DELETE)、允许的请求头(Content-Type)和是否允许发送Cookie。这样就允许了来自指定域名的跨域访问。

  1. 在客户端的 JavaScript 代码中,可以使用AJAX或Fetch API等方式发送跨域请求:
fetch('http://api.example.com/data', {method: 'GET',credentials: 'include' // 发送包含Cookie的请求
}).then(response => response.json()).then(data => {console.log(data); // 在控制台中打印获取到的数据}).catch(error => {console.error('Error:', error);});

在这个例子中,使用了Fetch API来发送GET请求到跨域服务器的 /data 路由,并通过 credentials: 'include' 选项来发送包含Cookie的请求。然后通过 response.json() 方法解析响应数据。

通过这种方式,客户端就能够通过CORS允许的方式与跨域服务器进行交互,获取数据并进行处理。例子仅供参考

  1. 代理服务器:可以设置一个代理服务器,将跨域请求转发到目标服务器并将响应返回给客户端。客户端向代理服务器发出请求,代理服务器再将请求发送到目标服务器,然后将响应返回给客户端。因为同源策略只存在于浏览器中,而代理服务器是在服务器端进行请求转发,所以不会受到同源策略的限制。

以下是一个使用代理服务器解决跨域问题的例子:

假设我们的前端应用运行在http://localhost:3000,而我们想要请求的跨域API位于http://api.example.com

  1. 在后端设置一个代理服务器来转发请求。以下是一个使用Node.js和Express框架实现的例子:
const express = require('express');
const request = require('request');const app = express();// 设置代理路由
app.get('/api/data', (req, res) => {const apiUrl = 'http://api.example.com/data'; // 目标API的URL// 转发请求到目标APIreq.pipe(request(apiUrl)).pipe(res);
});app.listen(8000, () => {console.log('Proxy server started');
});

在上述示例中,创建了一个代理服务器,将 /api/data 路由映射到目标 API 的 URL (http://api.example.com/data)。通过使用 request 模块将请求从代理服务器转发到目标 API,并将响应返回给前端应用。

  1. 在前端应用中发起请求。假设使用 Axios 进行网络请求,可以将请求发送到代理服务器的对应路由,如下所示:
import axios from 'axios';axios.get('http://localhost:8000/api/data').then(response => {console.log(response.data); // 在控制台中打印获取到的数据}).catch(error => {console.error('Error:', error);});

在这个例子中,向代理服务器的 /api/data 路由发送 GET 请求,代理服务器会将该请求转发到目标 API (http://api.example.com/data),然后将响应返回给前端应用。

  1. WebSocket:WebSocket 是一种全双工通信协议,它可以在客户端和服务器之间建立持久性的连接,实现实时数据传输。由于 WebSocket 是在单个 HTTP 连接上运行的,而不受同源策略的限制,因此可以解决跨域通信的问题。

  2. 使用反向代理:在服务器端配置一个反向代理,将所有的请求转发到目标服务器。客户端与反向代理进行通信,而反向代理与目标服务器之间是同源的,因此不会受到同源策略的限制。

以下是一个使用反向代理解决跨域问题的例子:

假设前端应用运行在 http://localhost:3000,而想要请求的跨域 API 位于 http://api.example.com

  • 在反向代理服务器上配置代理规则。可以使用常见的反向代理服务器,如Nginx或Apache。以下是一个使用Nginx的示例配置:
server {listen 80;server_name localhost;location /api/ {proxy_pass http://api.example.com/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}location / {proxy_pass http://localhost:3000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}

在上述示例中,配置了一个Nginx服务器,监听在80端口,并定义了两个代理规则。/api/ 路径下的请求将被转发到目标 API (http://api.example.com/),而其他所有请求将被转发到前端应用 (http://localhost:3000)。

  • 启动反向代理服务器。根据你的环境和配置方式,启动配置好的反向代理服务器。

  • 在前端应用中发送请求。前端应用可以直接发送请求到反向代理服务器,而不需要关心跨域问题。例如,使用Axios发送请求的示例代码如下:

import axios from 'axios';axios.get('/api/data').then(response => {console.log(response.data); // 在控制台中打印获取到的数据}).catch(error => {console.error('Error:', error);});

在这个例子中,将请求发送到反向代理服务器的 /api/data 路径,反向代理服务器会将该请求转发到目标 API (http://api.example.com/),然后将响应返回给前端应用。

React、Vue项目中如何解决跨域问题

在大型项目中,使用React、Vue或其他框架集成的方式,通常会有不同的方法来解决跨域问题。以下是一些常见的解决方案:

  1. 在React项目中,可以使用http-proxy-middleware等中间件来配置代理。以下是一个示例:
// setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');module.exports = function(app) {app.use('/api',createProxyMiddleware({target: 'http://api.example.com', // 目标服务器的URLchangeOrigin: true,pathRewrite: {'^/api': '', // 可选,用于重写路径},}));
};

在上述示例中,将所有以/api开头的请求代理到目标服务器http://api.example.com。可以根据实际情况进行配置。

  1. 在Vue项目中,可以在vue.config.js中配置代理。以下是一个示例:
// vue.config.js
module.exports = {devServer: {proxy: {'/api': {target: 'http://api.example.com', // 目标服务器的URLchangeOrigin: true,pathRewrite: {'^/api': '', // 可选,用于重写路径},},},},
};

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

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

相关文章

JDK 下载 华为云镜像站 地址

通常去 Oracle 官网下载 JDK&#xff0c;速度很慢而且需要账号登入 Oracle 官网下载地址 https://www.oracle.com/cn/java/technologies/downloads/archive/ JDK 下载 华为云镜像站 地址 https://repo.huaweicloud.com/java/jdk/ 我们下期见&#xff0c;拜拜&#xff01;

CentOS 8 GLIBC升级失败系统崩溃抢修实战

CentOS 8 GLIBC升级失败系统崩溃抢修实战 1. 恐怖的问题2. 参考解决方案3. 抢修实战3.1 准备工作3.2 抢修流程3.3 解决启动后Permission Denied3.3.1 参考方案3.3.2 解决 4. 总结 服务器为CentOS 8&#xff0c;支持glibc版本为2.28&#xff0c;但编译一个工具的glibc需求版本为…

MySQL-概述-数据模型SQL简介

数据库&#xff1a;DataBase&#xff08;DB&#xff09;&#xff0c;是存储和管理数据的仓库数据库管理系统&#xff1a;DataBase Management System&#xff08;DBMS&#xff09;&#xff0c;操作和管理数据库的大型软件。SQL&#xff1a;Structured Query Language&#xff0…

了解 PostgreSQL 体系结构

PostgreSQL 是客户端/服务器关系数据库管理系统 (RDMS)。 PostgreSQL 还支持各种扩展插件&#xff0c;例如 Azure Database for PostgreSQL 超大规模 Citus 选项中的 Citus 扩展插件。 将扩展插件加载到数据库中后&#xff0c;它将像任何内置功能一样正常运行。 PostgreSQL 也…

spring boot 多模块项目非启动模块的bean无法注入(问题记录)

之前有说我搭了一个多模块项目&#xff0c;往微服务升级&#xff0c;注入的依赖在zuodou-bean模块中&#xff0c;入jwt拦截&#xff0c; Knife4j ,分页插件等等&#xff0c;但是启动类在system中&#xff0c;看网上说在启动类上加SpringBootApplication注解默认扫描范围为自己…

树莓派4B安装系统 + 花生壳 + docker + portainer管理工具

1、安装树莓派系统 1、首先下载刷系统软件&#xff1a;下载 2、选择Raspberry Pi OS (64-bit)系统 3、设置配置文件 1、主机名 2、开启ssh服务 3、设置wifi账号密码 4、选择SD卡后开始烧录 2、设置系统时区 1、使用date -R查看当前系统时间 2、安装ntp插件&#xff1a;apt inst…

物联网(IoT):连接未来的万物之网

引言&#xff1a; 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过各种智能设备和传感器&#xff0c;使物体能够互联互通、收集和共享数据的网络。随着科技的不断进步和智能设备的普及&#xff0c;物联网的应用呈现出爆发式增长&#xff0c;对各…

哇~真的是你呀!今天是LINUX中的RSYNC服务

目录 前言 一、概述 二、特性 三、rsync传输模式 四、rsync应用 五、格式 六、配置文件 七、守护进程传输 八、rsyncinotfy实时同步 一、概述 rsync是linux 下一个远程数据同步工具;他可通过LAN/WAN快速同步多台主机间的文件和目录&#xff0c;并适当利用rsync 算法减少数据的…

微信小程序(二)

目录 1、input标签 一、表单绑定 1、数据绑定 2、输入获取 二、网络请求 1、介绍 2、注意 3、使用 4、基于Promise封装 三、自定义组件 1、创建 2、父向子组件通信 3、子向父组件通信 4、生命周期 四、vant weapp组件库 1、配置 2、使用 进入本章前的拓展&#…

代码随想录算法训练营第22天 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树&#xff0c;可以利用它的性质&#xff08;左子树上所有节点的值都小于根节点的值&#xff0c;右子树上所有节点的值都大于根节点的值&#xff09;找到两个节点的最近公共祖先。因此&#xff0c;可以进行如下操作&#xff1a;…

Jmeter(119)-函数threadNum妙用

今天的接口场景是&#xff1a;有N个用户需要每隔5秒去查询一次数据&#xff0c;也就是说N个用户会去循环执行同一个接口。一开始的时候将用户参数化时使用了counter&#xff0c; 要执行2个线程3次循环&#xff0c;发现每次循环时&#xff0c;接口中用户参数的数据就会不一样&am…

【AutoGluon_01】自动机器学习框架的安装与示例

文章目录 一、安装二、示例一 AutoGluon预测目标数据1、导入数据2、训练3、预测4、评估5、小结 三、示例二 AutoGluon多模态预测&#xff08;Multimodal Prediction&#xff09;1、导入数据2、训练3、预测4、评估 四、示例三 AutoGluon进行时间序列预测1、导入数据2、训练3、预…

漫谈大数据时代的个人信息安全(三)——“点赞之交”

大数据时代的个人信息安全系列三&#xff1a;“点赞之交” 1. 点赞之交2. 点赞诈骗3. 个人信息保护小贴士 互联网就像公路&#xff0c;用户使用它&#xff0c;就会留下脚印。 每个人都在无时不刻的产生数据&#xff0c;在消费数据的同时&#xff0c;也在被数据消费。 近日&am…

AJAX异步请求JSON数据格式

目录 前言 1.AJAX的实现方式 1.1原生的js实现方式 1.2JQuery实现方式 2.1语法 3.JSON数据和Java对象的相互转换 3.1将JSON转换为Java对象 3.2将Java对象转换为JSON 前言 AJAX&#xff1a;ASynchronous JavaScript And XML 异步的JavaScript 和 XML。 Ajax 是一种在…

git导出提交日志

%ai是2023-06-16 14:49:10 0800时间格式 Git - 查看提交历史Git 官方中文操作文档 Git - 查看提交历史 导出excel,csv格式 筛选作者的提交--author"ayuyuer" git log --prettyformat:"%h","%an","%ae","%ai","%s&qu…

微信小程序

页面跳转&#xff1a; navigator 显示跳转 跳转普通页面跳转 tab栏页面 open-type"switchTab"回退上一个 open-type"navigateBack" <navigator url"/pages/detail/detail?usernamecc&addresschengdu">detail</navigator>js跳…

Spring Boot 各种回滚骚操作实战(自动回滚、手动回滚、部分回滚)

概念 事务定义 事务&#xff0c;就是一组操作数据库的动作集合。事务是现代数据库理论中的核心概念之一。如果一组处理步骤或者全部发生或者一步也不执行&#xff0c;我们称该组处理步骤为一个事务。当所有的步骤像一个操作一样被完整地执行&#xff0c;我们称该事务被提交。…

springboot sentinel 整合 规则详情和代码实现-分布式/微服务流量控制

文章目录 sentinel控制台安装目标版本说明sentinel 规则整合验证pom.xml配置注解拦截资源控制规则---内存模式测试controller客户端接入控制台 测试sentinel控制台接口调用 下一篇&#xff1a;配置持久化策略规则外传 sentinel控制台安装 下载地址&#xff1a;https://github.…

Go语言之并发编程练习,GO协程初识,互斥锁,管道:channel的读写操作,生产者消费者

GO协程初识 package mainimport ("fmt""sync""time" )func read() {defer wg.Done()fmt.Println("read start")time.Sleep(time.Second * 3)fmt.Println("read end") }func listenMusci() {defer wg.Done()fmt.Println(&qu…

vue 下拉框显示从后端请求的数据

下拉框<!-- 给产品添加推广人员弹出框 --><el-dialog :title"titlePerson" :visible.sync"openAddPerson" width"1000px" append-to-body><el-select v-model"this.bindingProductPerson.recommendId" filterable plac…