前端跨域请求原理及实践

东方通部署跨域问题 东方通部署跨域请求问题 阅读详情

一、 跨域请求的含义

浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。

一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用。这也是我们下面实践的理论基础。我们利用 NodeJs 创建了两个服务器,分别监听 3000、 3001 端口(下面简称 服务器3000 与 服务器3001 ),由于端口号不一样,这两个服务器以及服务器上页面通信构成了跨域请求。

在服务器3000 上有如下的页面:

服务器3000 上的请求页面中包含如下 JavaScript 代码:

$(function() {
    $("#submit").click(function() {
        var data = {
            name: $("#name").val(),
            id: $("#id").val()
        };
        $.ajax({
            type: 'POST',
            data: data,
            url: 'http://localhost:3000/ajax/deal',
            dataType: 'json',
            cache: false,
            timeout: 5000,
            success: function(data) {
                console.log(data)
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log('error ' + textStatus + ' ' + errorThrown);
            }
        });
    });
});

服务器3000 对应的处理函数为

pp.post('/ajax/deal', function(req, res) {
    console.log("server accept: ", req.body.name, req.body.id)
    var data = {
        name: req.body.name + ' - server 3000 process',
        id: req.body.id + ' - server 3000 process'
    }
    res.send(data)
    res.end()
})

请求页面返回结果:

此处数据处理成功。

由于数据请求一般都是由页面发送数据字段,服务器根据这些字段作相应的处理,如数据库查询,字符串操作等等。所以我们这里简单的处理数据(在数据后面加上字符串‘server 3000 process’),并且返回给浏览器,表示数据经过服务器端处理。

如果让 服务器3000 上的页面向 服务器 3001 发起请求会怎样呢?

将请求页面中的 ajax 请求路径改为:

$.ajax({
    ...
    url: 'http://localhost:3001/ajax/deal',
    ...
});

服务器3001 对应的处理函数与 服务器3000 类似:

app.post('/ajax/deal', function(req, res) {
    console.log("server accept: ", req.body.name, req.body.id)
    var data = {
        name: req.body.name + ' - server 3001 process',
        id: req.body.id + ' - server 3001 process'
    }
    res.send(data)
    res.end()
})

结果如下:

结果证明了我们上面所说的端口号不同,发生了跨域请求的调用。

需要注意的是,服务器 3001 控制台有输出:

server accept: chiaki 3001

这说明跨域请求并非是浏览器限制了发起跨站请求,而是请求可以正常发起,到达服务器端,但是服务器返回的结果会被浏览器拦截。

二、 利用 JSONP 实现跨域调用

说道跨域调用,可能大家首先想到的或者听说过的就是 JSONP 了。

2.1 什么是JSONP

JSONP (JSON with Padding or JSON-P) is a JSON extension used by web developers to overcome the cross-domain restrictions imposed by browsers’ same-origin policy that limits access to resources retrieved from origins other than the one the page was served by. In layman’s terms, one website cannot just simply access the data from another website.

It was developed because handling a browsers’ same origin policy can be difficult, so using JSONP abstracts the difficulties and makes it easier.

JSON stands for “JavaScript Object Notation”, a format by which object fields are represented as key-value pairs which is used to represent data.

JSONP 是 JSON 的一种使用模式,可以解决主流浏览器的跨域数据访问问题。其原理是根据 XmlHttpRequest 对象受到同源策略的影响,而

这样从服务器返回的代码就可以直接在这个 script 标签中运行了。下面我们自己实现一个 JSONP:

服务器 3000请求页面的 JavaScript 代码中,只有回调函数 jsonpCallback:

function jsonpCallback(data) {
    console.log("jsonpCallback: "+data.name)
}

服务器 3000请求页面还包含一个 script 标签:

服务器 3001上对应的处理函数:

app.get('/jsonServerResponse', function(req, res) {
    var cb = req.query.jsonp
    console.log(cb)
    var data = 'var data = {' + 'name: $("#name").val() + " - server 3001 jsonp process",' + 'id: $("#id").val() + " - server 3001 jsonp process"' + '};'
    var debug = 'console.log(data);'
    var callback = '$("#submit").click(function() {' + data + cb + '(data);' + debug + '});'
    res.send(callback)
    res.end()
})

与上面一样,我们在所获取的参数后面加上 “ – server 3001 jsonp process” 代表服务器对数据的操作。从代码中我么可以看到,处理函数除了根据参数做相应的处理,更多的也是进行字符串的拼接。

最终的结果为:

2.4 JSONP 总结

至此,我们了解了 JSONP 的原理以及实现方式,它帮我们实现前端跨域请求,但是在实践的过程中,我们还是可以发现它的不足:

只能使用 GET 方法发起请求,这是由于 script 标签自身的限制决定的。

不能很好的发现错误,并进行处理。与 Ajax 对比,由于不是通过 XmlHttpRequest 进行传输,所以不能注册 success、 error 等事件监听函数。

三、 使用 CORS 实现跨域调用

3.1 什么是 CORS?

Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。

3.2 CORS 的实现

还是以 服务器 3000 上的请求页面向 服务器 3001 发送请求为例。

服务器 3000 上的请求页面 JavaScript 不变,如下:

$(function() {
    $("#submit").click(function() {
        var data = {
            name: $("#name").val(),
            id: $("#id").val()
        };
        $.ajax({
            type: 'POST',
            data: data,
            url: 'http://localhost:3001/cors',
            dataType: 'json',
            cache: false,
            timeout: 5000,
            success: function(data) {
                console.log(data)
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log('error ' + textStatus + ' ' + errorThrown);
            }
        });
    });
});

服务器 3001上对应的处理函数:

app.post('/cors', function(req, res) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    var data = {
        name: req.body.name + ' - server 3001 cors process',
        id: req.body.id + ' - server 3001 cors process'
    }
    console.log(data)
    res.send(data)
    res.end()
})

在服务器中对返回信息的请求头进行了设置。

最终的结果为:

3.3 CORS 中属性的分析

  1. Access-Control-Allow-Origin

The origin parameter specifies a URI that may access the resource. The browser must enforce this. For requests without credentials, the server may specify “*” as a wildcard, thereby allowing any origin to access the resource.

  1. Access-Control-Allow-Methods

Specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. The conditions under which a request is preflighted are discussed above.

  1. Access-Control-Allow-Headers

Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

3.4 CORS 与 JSONP 的对比

  1. CORS 除了 GET 方法外,也支持其它的 HTTP 请求方法如 POST、 PUT 等。

  2. CORS 可以使用 XmlHttpRequest 进行传输,所以它的错误处理方式比 JSONP 好。

  3. JSONP 可以在不支持 CORS 的老旧浏览器上运作。

四、 一些其它的跨域调用方式

4.1 window.name

window对象有个name属性,该属性有个特征:即在一个窗口 (window) 的生命周期内,窗口载入的所有的页面都是共享一个 window.name 的,每个页面对 window.name 都有读写的权限,window.name 是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

4.2 window.postMessage()

这个方法是 HTML5 的一个新特性,可以用来向其他所有的 window 对象发送消息。需要注意的是我们必须要保证所有的脚本执行完才发送 MessageEvent,如果在函数执行的过程中调用了他,就会让后面的函数超时无法执行。

避开奸商套路!手把手教你用Thaiphoon Burner和CPU-Z,一眼看穿内存SPD信息有没有被篡改 本文教你使用Thaiphoon Burner和CPU-Z工具,快速识别内存SPD信息是否被篡改,避免购买到虚标频率或假冒颗粒的内存条。通过详细步骤和实战案例,帮助用户掌握内存检测技巧,确保硬件购买的透明度和安全性。 阅读详情

相关推荐

别再花屏了!手把手教你用STM32CubeIDE搞定LVGL 8.3移植(附完整源码)

本文详细介绍了如何在STM32CubeIDE环境下成功移植LVGL 8.3,解决常见的花屏问题。从环境配置、显示驱动优化到编译警告处理,提供完整的实战方案和源码示例,帮助开发者快速实现流畅的嵌入式GUI界面。特别针对STM32平台的DMA2D加速和内存管理进行了深度优化。

weixin_33739646的博客 242

解决跨域问题

在这之前我总共遇到过两种跨域问题,一个是后台的tomcat出现的跨域问题,一个是iis出现的跨域问题 1:tomcat跨域问题解决: <filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORS...

Fe_lin的博客 891

Flutter 直接调用so动态库,或调用C/C++源文件内函数

我把 .so 文件尝试放过好几个目录/lib/,最终都会报这个错误,现在才知道库文件需要放在你根本想象不到的地方!!!尝试了一些方法还是不行后我放弃了 ffi,想着用 Flutter 的 MethodChannel 桥接 android/ios 原生,再让原生去调 native 层。一顿操作把Android端的搞定了,当然中间涉及到 Kotlin和C++ 层的数据类型映射的痛苦,而且业务函数也不像一个 helloworld 那么简单,别提有多痛苦了。

开发以大橘为重 8350

跨域资源共享(cors)问题(前端服务器是东方通)

2、定义CROS源的白名单,仅允许可信源的跨域请求;3、Access-Control-Allow-Credentials标头设置为true时,允许跨域请求中带有凭证数据,非必要情况下建议把值设置成false;4、避免配置“ACCESS-Control-Allow-Origin”为通配符“*”;当服务器开启CORS功能时,如果响应包返回的报文头Access-Control-Allow-Credentials为true时,攻击者可利用改配置缺陷创建一个特殊脚本去发送cors请求,从而窃取用户的敏感数据。

丫丫的博客 575

NVIDIA DGX Spark 深度应用解析:从大模型训练到边缘推理的完整实践指南

内存管理:充分利用统一内存架构,避免不必要的数据传输批处理大小:根据模型大小调整批处理大小以优化内存使用精度选择:在精度损失可接受范围内使用较低精度计算流水线优化:重叠计算和数据传输操作DGX Spark作为一个专门的AI计算平台,在大模型开发的各个阶段都能发挥重要作用。从数据预处理到模型训练,从微调到推理部署,其统一内存架构和强大的计算能力为AI开发者提供了前所未有的本地开发体验。需要注意的是,虽然DGX Spark性能强大,但合理的算法设计和系统优化仍然是获得最佳性能的关键。

time_days的博客 2869

YOLOv12超参数智能优化:基于内置Ray Tune的自动化调优实战指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有! 目标检测模型的性能瓶颈往往源于超参数配置不当。传统手动调优方式不仅耗时耗力,且难以找到全局最优解。YOLOv12集成的Ray Tune框架为解决这一难题提供了完整方案,通过分布式异步优化算法,可实现超参数搜索效率的指数级提升。实际测试表明,采用Ray Tune自动调优的YOLOv12模型,在COCO数据集上mAP指标平均提升3.8%,收敛速度加快2.1倍。在VisDrone无人机数据集上的跨域测试

LXY_LOVE36的博客 119

POST http://localhost:3001/graphql 500 (Internal Server Error)

我有一个 React 前端和一个 Node.js 后端,前端使用 React 和 Apollo Client 进行 GraphQL 查询,后端是一个使用 Express.js 和 GraphQL 构建的 API。在开发过程中,我遇到了在前端(运行在 3001 端口)向后端(运行在 3000 端口)发起跨域请求的问题。尽管尝试了配置代理的方式,但仍然无法解决跨域请求被阻止的问题。经过反复尝试和排查,最终找到了一个有效的解决方法:在后端的。文件中添加下面这行即可,别忘重启服务器。

Joe_Hall_Lee的博客 1027

Open3D 计算FPFH特征【2025最新版】

FPFH特征描述子的python实现,本文最新更新时间为:2025年3月18日。

点云侠的博客 5273

前端跨域请求get_前端跨域请求原理及实践

一、 跨域请求的含义浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用。这也是我们下面实践的理论基础。我们利用 NodeJs 创建了两个服务器,分别监听 3000、 3001 端口(下面简称 服务器...

weixin_35513425的博客 1085

uniapp [微信小程序] - 详解微信小程序端接入mqtt全流程及示例源码教程,uniApp微信小程序端如何接入MQTT插件并实现连接/断开+发布订阅+消息队列+离线重连等各种示例代码(开箱即用)

uniapp微信小程序接入MQTT,uniapp中使用mqtt,uniapp 微信小程序端接入mqtt示例代码教程,适用于微信小程序的MQTT插件,uniapp开发微信小程序连接mqtt,uniApp微信小程序接入MQTT协议,uniapp vue3微信小程序使用MQTT的小例子接入流程,使用uniapp开发小程序接入mqtt,如何在uniapp项目中使用mqtt,uniapp mqtt的使用示例,mqtt连接报错,如何在项目里集成mqtt,Mqtt协议,主动连接mqtt,订阅消息,实现发布,订阅和接收消息

🏆 前端领域优质创作者 2881

【代码审计】专栏文章汇总

代码审计基础 代码审计基础 源代码审计思路(上) 源代码审计思路(下) 常见漏洞审计 认证会话管理(上) 认证会话管理(下) 输入输出验证 授权管理审计 业务安全审计 第三方组件审计

武天旭的博客 4845

请求跨域前端解决_前端跨域请求原理及实践(转载)

一、 跨域请求的含义浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用。这也是我们下面实践的理论基础。我们利用 PHP 创建了两个服务器(下面简称 服务器test1与 服务器test2 )在服务器t...

weixin_26805451的博客 271

AI安全护栏评测:TrustedExecBench如何量化评估大模型防护能力

在人工智能和机器学习领域,模型安全对齐是确保AI系统可靠、可控的核心技术。其原理是通过设计安全机制(即“护栏”)来约束模型行为,防止生成有害、偏见或越界内容。这项技术的核心价值在于平衡AI能力与风险管控,是可信AI部署的基石。应用场景广泛覆盖内容审核、对话系统、代码生成等需要人机交互的领域。本文聚焦的TrustedExecBench项目,正是针对“护栏”性能量化评估这一痛点,提供了一个标准化、自动化的开源评测框架。该工具通过构建多维度的恶意测试套件,并引入基于模型的动态评判机制,能够系统性地检验大语言模型在

weixin_42525428的博客 378

转---前端跨域请求原理及实践

最近决定把自己收藏的文章都放到博客园里来存着,哈哈~~ 作者:高鹏 tingandpeng.com/2016/09/05/前端跨域请求原理及实践/ 一、 跨域请求的含义 浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。 一般的,只要网站的 协议名protocol、 主机host、 端口号p...

weixin_30274627的博客 86

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: 分析页面延迟加载的实现
下一篇: VisualSVN Server提交前检查备注信息
星海设计
博客等级 码龄19年 13粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星海设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值