首页 > 其他分享 >什么是跨域?什么情况会触发跨域,应该如何解决跨域?

什么是跨域?什么情况会触发跨域,应该如何解决跨域?

时间:2024-05-27 18:45:03浏览次数:22  
标签:触发 请求 什么 CORS import com example 跨域

什么是跨域?什么情况会触发跨域,以及如何解决跨域?

什么是跨域?

跨域(Cross-Origin)是指在一个网页中,发起对不同源(域名、协议或端口不同)的资源请求。由于安全原因,浏览器默认会阻止这种跨域请求,这是因为同源策略(Same-Origin Policy)的限制。同源策略是浏览器的一种安全机制,用于防止不同来源的资源之间的恶意交互。

同源策略

同源策略要求:

  1. 协议相同(例如,都是HTTP或HTTPS)。
  2. 域名相同(例如,都是example.com)。
  3. 端口相同(例如,都是80端口或443端口)。

如果三个条件中有任何一个不满足,浏览器就会认为这是一个跨域请求,默认情况下会被阻止。

触发跨域的情况

跨域请求通常是由浏览器发起的,当网页尝试从一个不同的源(域名、协议或端口不同)请求资源时,就会触发跨域。以下是一些常见会触发跨域请求的情况:

  1. 不同域名

    // 当前网页在 example.com
    fetch('https://another-domain.com/api/data'); // 跨域请求
    
  2. 不同子域名

    // 当前网页在 sub.example.com
    fetch('https://api.example.com/data'); // 跨域请求
    
  3. 不同协议

    // 当前网页在 https://example.com
    fetch('http://example.com/api/data'); // http 与 https 不同
    
  4. 不同端口

    // 当前网页在 http://example.com:80
    fetch('http://example.com:8080/api/data'); // 端口 80 与 8080 不同
    

如何解决跨域?

为了在合法的情况下允许跨域请求,有多种解决方法:

1. 使用JSONP(JSON with Padding)

JSONP是一种传统的解决跨域请求的方法,通过动态插入<script>标签来实现跨域请求。它仅支持GET请求。

<script>
    function handleResponse(data) {
        console.log(data);
    }

    var script = document.createElement('script');
    script.src = 'https://example.com/data?callback=handleResponse';
    document.body.appendChild(script);
</script>

2. 使用CORS(Cross-Origin Resource Sharing)

CORS是W3C标准,是一种更现代和强大的解决跨域请求的方法。服务器通过设置HTTP头来允许跨域请求。

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

在服务器端,可以通过编程来设置这些头。例如,在Node.js和Express中:

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

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
});

app.get('/data', (req, res) => {
    res.json({ message: 'This is CORS-enabled for all origins!' });
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

3. 使用服务器代理

通过在同源服务器上设置一个代理服务器,由代理服务器去请求目标服务器,从而避免跨域问题。

在Node.js中,可以使用http-proxy-middleware:

const { createProxyMiddleware } = require('http-proxy-middleware');

app.use('/api', createProxyMiddleware({
    target: 'https://example.com',
    changeOrigin: true,
}));

4. 使用Iframe + PostMessage

通过嵌入iframe并使用postMessage在父窗口和子窗口之间进行通信。

<!-- Parent Page -->
<iframe id="myFrame" src="https://example.com"></iframe>
<script>
    var frame = document.getElementById('myFrame');
    window.addEventListener('message', function(event) {
        console.log('Message received:', event.data);
    });
    frame.contentWindow.postMessage('Hello from parent', 'https://example.com');
</script>

Spring中解决跨域

在Spring开发的服务端API中,默认情况下会遵循同源策略,不会自动允许跨域请求。为了允许跨域请求,需要显式地配置CORS。

1. 使用全局CORS配置

可以通过在配置类中使用@ConfigurationWebMvcConfigurer接口来设置全局的CORS配置。

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 {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允许所有路径
                .allowedOrigins("*") // 允许所有来源
                .allowedMethods("GET", "POST", "PUT, DELETE, OPTIONS") // 允许的方法
                .allowedHeaders("*") // 允许的请求头
                .allowCredentials(true) // 允许携带凭证
                .maxAge(3600); // 预检请求的缓存时间
    }
}

2. 使用注解配置CORS

可以在控制器方法或类上使用@CrossOrigin注解来设置CORS配置。

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin(origins = "http://example.com") // 允许来自 http://example.com 的请求
@RestController
public class MyController {

    @GetMapping("/api/data")
    public String getData() {
        return "Hello, World!";
    }
}

3. 使用过滤器配置CORS

可以通过自定义过滤器来配置CORS,这种方式可以提供更灵活的控制。

import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class SimpleCORSFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

总结

跨域请求是由浏览器的同源策略引起的,通过配置CORS,可以在合法的情况下允许跨域请求。在实际应用中,根据具体需求选择合适的配置方法是非常重要的。例如,如果需要全局的CORS配置,使用WebMvcConfigurer接口会更为简便;如果只需要对某些特定的控制器或方法进行配置,可以使用@CrossOrigin注解。通过这些方法,可以确保在多源环境下的数据请求安全、可靠。

标签:触发,请求,什么,CORS,import,com,example,跨域
From: https://www.cnblogs.com/irobotzz/p/18216214

相关文章

  • DNS 安全为什么非常重要?
    DNS(DomainNameSystem)是域名系统的缩写,它是一个分布式数据库系统,用于将人们易于记忆的域名(如www.example.com)转换成计算机能够理解的IP地址(如192.0.2.1)。DNS的主要作用是将用户的域名查询请求转换为IP地址,从而使用户能够方便地访问互联网上的资源。DNS的重要性在访问一个网站时......
  • springboot2.7.18配置跨域
    一.springboot整合security后一般要配置security的跨域和mvc的跨域才能实现跨域1.spring-security配置跨域@BeanpublicSecurityFilterChainfilterChain(HttpSecurityhttp)throwsException{http.csrf().disable().cors();returnhttp.build();......
  • 淘宝扭蛋机与盲盒小程序的区别是什么
    淘宝扭蛋机与盲盒小程序在核心理念上均为用户提供了有趣且充满惊喜的购物体验,但在具体实现和功能上存在一些区别。以下是它们之间的主要区别:商品选择与展示:淘宝扭蛋机小程序主要模拟了真实的扭蛋机体验,提供了丰富多样的扭蛋商品,涵盖了动漫、游戏、影视、明星等各个领域。......
  • 什么是形式化方法
    形式化方法是一种基于数学和逻辑的软件开发方法,其核心目的是通过严格的数学和逻辑推理来验证软件系统的正确性和可靠性。下面我将从定义、应用、特点和优势等方面详细解释形式化方法。一、定义形式化方法,英文名为“formalmethods”,是一种在逻辑科学中分析、研究思维形式结构的......
  • Facebook海外户&海外三不限户是什么?
        在当今的互联网时代,社交媒体已经成为人们沟通交流不可或缺的一部分,而Facebook作为全球最大的社交网络平台之一,吸引着数以亿计的用户,也成为跨境电商们推广产品、扩大品牌影响力的必争之地。Facebook广告户的开户渠道也有很多中,市面上的FB国内三不限户,海外户,二不限户,......
  • 绿豆蛙的归宿(别问我为什么会写这玩意)
    声明一下,概率与期望这块属实没有看懂,如果有什么唐氏错误多多包容正推不很显然,对于边(i,j),j的期望值是i的期望值加上边权除以i的出度(从i出发边的条数),我对于这个的理解是假设从i出发有k条边,j是其中一个,那么到j的可能就是\(\frac{1}{k}\)即\(\frac{1}{out[i]}\)所以会有\(......
  • 阿里面试:NIO为什么会导致CPU100%?
    在Java中总共有三种IO类型:BIO(BlockingI/O,阻塞I/O)、NIO(Non-blockingI/O,非阻塞I/O)和AIO(AsynchronousI/O,异步I/O),它们的区别如下:在JDK1.4之前,只有BIO一种模式,其开发过程相对简单,新来一个连接就会创建一个新的线程处理,但随着请求并发度的提升,BIO很快遇到了性能瓶颈。......
  • 1、 为什么软件开发周期总是预估的2~3倍? 2、什么是分而治之? 3、了解 WBS
    1、为什么软件开发周期总是预估的2~3倍?首先,软件开发中经常会有需求变更的情况,客户或者利益相关者可能会提出新的需求或者改变现有的需求,这就得调整计划,增加了开发时间。其次,开发人员的技术和经验也会影响开发周期,如果技术不够或者经验不足,那就容易出现错误和问题,导致开发周期延长......
  • 开发者为什么需要“不良代码”
    “从未犯过错误的人也从未有过新发现。”—塞缪尔·斯迈尔斯想象一下场景:苏格兰,1928年。可能在下雨,一位科学家不小心让他的培养皿被霉菌污染了,他并不知道这个错误最终将拯救数百万人的生命,这项伟大的发现就是青霉素。这位科学家的名字就是亚历山大·弗莱明,他一个小小的......
  • Windows远程桌面是什么?
    Windows远程桌面是一种远程桌面协议,允许用户通过网络连接到远程Windows计算机,并在本地操作远程计算机。它为用户提供了访问远程计算机的便利性,可以在不同地区的电脑或设备之间进行信息远程通信。天联解决方案在远程桌面技术中,天联是一个可靠的解决方案。天联利用组网技术,可......