• 解决跨域的几种方式


    解决跨域的几种方式

    JSONP

    利用script标签可以跨域加载资源的特性,通过动态创建一个script标签,然后将响应数据作为回调函数的参数返回,从而实现跨域请求资源。该方式只支持 GET 请求方式,且不支持发送 POST 等其它请求。

    客户端代码:

    const script = document.createElement("script");
    script.src = "http://example.com/data.js?callback=handleResponse";
    document.body.appendChild(script);
    
    function handleResponse(data) {
    	console.log(data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    服务端应返回如下格式的响应数据:

    handleResponse({ status: "ok", data: { foo: "bar" } });
    
    • 1

    客户端创建一个script标签并添加到 DOM 中,指定 src 属性为带有 callback 参数的请求 URL,服务端会将响应数据以回调函数的参数形式返回,从而实现获取数据的目的。当响应数据返回后,客户端自行定义的回调函数会被触发。

    CORS(跨域资源共享)

    该方式需要在服务端进行配置,通过设置响应头 Access-Control-Allow-Origin 允许跨域访问的来源,可以实现跨域请求资源。此方法更为安全,且支持所有请求方法。

    客户端代码:

    fetch("http://example.com/data.json", {
    	method: "GET",
    	mode: "cors",
    })
    	.then((response) => response.json())
    	.then((data) => console.log(data))
    	.catch((error) => console.error(error));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    服务端代码:

    // 允许指定来源的跨域访问,例如允许从http://localhost:8080域名下访问
    app.use((req, res, next) => {
    	res.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
    	res.setHeader("Access-Control-Allow-Headers", "Content-Type");
    	next();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    客户端使用fetch函数发送跨域请求,通过设置modecors来表明跨域方式。服务端使用 Node.js 的 Express 框架,通过设置响应头的Access-Control-Allow-Origin允许从指定来源跨域访问。当服务端成功处理请求并响应数据后,客户端通过response.json()将响应体解析为 JSON 格式的数据。

    代理

    在同源域名下,通过服务端代理请求目标网站的资源,再将响应结果返回给客户端,从而实现跨域访问目标资源。该方式相对复杂,但是可以实现所有请求方法。

    前端通过代理方式实现跨域,可以通过配置一个 Node.js 的 Express 代理服务器,然后在前端发送请求时,将请求发送至代理服务器,代理服务器再将请求转发至目标服务器,获取响应后再返回给前端。具体步骤如下:

    1. 创建一个 Node.js 的 Express 代理服务器。
    const express = require("express");
    const http = require("http");
    const app = express();
    
    const PORT = 3000;
    const TARGET_SERVER = "http://example.com";
    
    // 转发请求到目标服务器
    app.use("/", (req, res) => {
    	const targetUrl = TARGET_SERVER + req.url;
    	const proxy = http.request(targetUrl, (response) => {
    		response.pipe(res);
    	});
    
    	req.pipe(proxy);
    });
    
    app.listen(PORT, () => {
    	console.log(`Proxy server is running on port ${PORT}`);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在上面的例子中,我们创建了一个代理服务器,运行在3000端口上,该服务器可以接收任意请求并将请求转发到目标服务器http://example.com上,然后将响应返回客户端。

    1. 在前端通过代理服务器发送请求
    fetch("/api/data")
    	.then((response) => response.json())
    	.then((data) => console.log(data))
    	.catch((error) => console.error(error));
    
    • 1
    • 2
    • 3
    • 4

    在前端使用 fetch 函数来发送需要跨域的请求,由于代理服务器监听的是 3000 端口,所以这里的请求 URL 应该是代理服务器的路径/api/data。

    上述方法仅在开发环境下使用,而不适合在生产环境中使用,因为将会涉及更多的安全问题,例如如何保证用户的数据处于安全的状态。

  • 相关阅读:
    关注短视频的“时间”,找准用户活跃时间,高流量也不是梦
    “深入理解机器学习性能评估指标:TP、TN、FP、FN、精确率、召回率、准确率、F1-score和mAP”
    【Mac开发环境搭建】Docker安装Redis、Nacos
    MQTT(详解)
    文件包含之日志中毒(User-Agent)
    new`是如何创建对象实例的?
    python多进程与多线程
    用go设计开发一个自己的轻量级登录库/框架吧(业务篇)
    Servlet | ServletConfig接口、ServletContext接口详解
    本地部署和运行大型语言模型(Large Language Models, LLMs)的工具Ollama
  • 原文地址:https://blog.csdn.net/zouhai1/article/details/132775968