跨域请求方案整理实践

项目场景:

调用接口进行手机验证提示,项目需要调用其它域名的接口,导致前端提示跨域问题


问题描述

前端调用其他域名接口时报错提示:

index.html#/StatisticalAnalysisOfVacancy:1 Access to XMLHttpRequest at 'http://xxxxx/CustomerService/template/examineMessage' from origin 'http://xxxxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.


原因分析:

在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。

这个问题是随着AJAX的兴起,Web 应用对跨域访问的需求就越来越多,AJAX在进行跨域请求的时候受到浏览器安全限制。

浏览器出于安全的考虑,引入了同源策略。这种策略会对页面上执行的js访问资源的时候进行限制,比如不能直接通过js访问不同源之下的页面DOM结构,同时在对不同源发送请求时也无法获取到服务器响应内容(服务器会正常处理请求并返回响应内容,但是返回的内容被浏览器拦截掉了)。

什么是同源策略?

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

同源策略将限制以下几种行为:

  1. Cookie、LocalStorage 和 IndexDB 无法读取
  2. DOM 和 Js对象无法获得
  3. 常见的跨域场景

  4. URL说明是否允许通信
    http://www.domain.com/a.js http://www.domain.com/b.js同一域名,不同文件或路径允许
    http://www.domain.com:8000/a.js http://www.domain.com/b.js同一域名,不同端口不允许
    http://www.domain.com/a.js https://www.domain.com/b.js同一域名,不同协议不允许
    http://www.domain.com/a.js http://192.168.4.12/b.js域名和域名对应相同ip不允许
    http://www.domain.com/a.js http://x.domain.com/b.js http://domain.com/c.js主域相同,子域不同不允许
    http://www.domain1.com/a.js http://www.domain2.com/b.js不同域名不允许

解决方案:

解决方案

jsonp跨域

通常为了减轻web服务器的负载,把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,可以通过动态创建script,再请求一个带参网址实现跨域通信。

前端实现代码:

<script type="text/javascript"> function onLogin(res){console.log(res);}
</script>//引用文件的方式
<script type="text/javascript" src="https://www.devpoint.com/login?user=devpoint&callback=onLogin">//AJAX,以jquery.js
<script type="text/javascript"> $.ajax({url:"https://www.devpoint.com/login",type:"get",dataType:"jsonp", //请求方式为jsonp jsonpCallback:"onLogin", //自定义回调函数名data:{}});
</script>

服务端实现代码(PHP):

echo "onLogin({"result":"success", "user": "doweb"})"
局限:仅限GET请求

document.domain + iframe 跨域

实现原理:两个页面通过js的document.domain强制设置为相同主域来达到同域的效果,即相当于iframe中的页面为通信代理页面,代理页面必须部署在与后端服务器同源站点下。

主页面:(假定访问路径为:https://blog.devpoint.cn/login.html )

<iframe id="proxyIframe" src="https://api.devpoint.cn/proxy.html"></iframe>
<script type="text/javascript"> document.domain = "devpoint.cn";const user = "devpoint";const elemIframe = document.getElementById("proxyIframe");elemIframe.login(user,function(res){console.log(res);});
</script>

代理页面:https://api.devpoint.cn/proxy.html

<script type="text/javascript"> document.domain = "devpoint.cn";function ajax(data,callback){//此处实现与真正的后端通信}function login(user,callback){ajax(data,callback);}
</script>
局限:仅限主域名一致,子域名不同的跨域。

location.hash + iframe跨域

实现原理: a欲与b跨域通信,通过中间页c来实现。
三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。
具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。

a.html(http://www.devpoint.cn/a.html

<iframe id="iframe" src="http://www.devpoint.cn/b.html" style="display:none;"></iframe>
<script type="text/javascript"> var iframe = document.getElementById("iframe"); //向b.html传hash值 setTimeout(function() {iframe.src = iframe.src + "#user=devpoint"; }, 1000); // 开放给同域c.html的回调方法 function onCallback(res) { alert("data from c.html ---> " + res); }
</script>

b.html(http://www.doweb.me/b.html

<iframe id="iframe" src="http://www.doweb.me/c.html" style="display:none;"></iframe>
<script type="text/javascript">var iframe = document.getElementById("iframe"); //监听a.html传来的hash值,再传给c.htmlwindow.onhashchange = function () {iframe.src = iframe.src + location.hash; };
</script>

c.html(http://www.devpoint.cn/c.html

<script type="text/javascript">//监听b.html传来的hash值window.onhashchange = function () {//再通过操作同域a.html的js回调,将结果传回  window.parent.parent.onCallback("hello: " + location.hash.replace("#user=", "")); };
</script>
局限:繁琐,且location.hash传递的值长度有限

postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递
  • 上面三个场景的跨域数据传递

实现原理:postMessage(data,origin)方法接受两个参数:

  • data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
  • origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

CORS跨域

普通跨域请求:服务端设置Access-Control-Allow-Origin即可,前端无须设置;
跨域请求要带cookie:前后端都需要设置。
需注意的是:由于同源策略的限制,所读取的cookie为跨域请求接口所在域的cookie,而非当前页。如果想实现当前页cookie的写入。

目前,所有浏览器都支持该功能,CORS也已经成为主流的跨域解决方案。在项目中的DEBUG功能的跨域请求就是使用这个方案。

前端设置:需要在请求头中设置withCredentials属性

headers: {"x-fdn-sign": apiSign,withCredentials: "true"
}

服务端设置

response.setHeader("Access-Control-Allow-Origin", "*"); // 若有端口需写全(协议+域名+端口)
response.setHeader("Access-Control-Allow-Credentials", "true");

我个人是使用 jsonp跨域 解决的

$.ajax({url:'htt.www:5060/CustomerService/template/examineMessage',data: {'PhoneNumbers':applicantTel,'state':auditstatus},type:"post",dataType:"jsonp",jsonpCallback:"onLogin", //自定义回调函数名success:function (result) {console.log("修改变更==",result)if(result.code==200){table.reload("recordOfRepair1");}else{layer.msg(result.message)}}});

后端也可以解决只需要在接口处加个注解即可

@CrossOrigin 

注意: Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin ;

或者也可参考这位博主的

 9种常见的前端跨域解决方案(详解)_前端解决跨域问题_时清云的博客-CSDN博客

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

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

相关文章

UniApp创建项目HelloWorld

浏览器预览效果镇楼 普通项目创建 点击创建完成后&#xff0c;就如下所示 确实和微信小程序开发差不多。只是稍微换了一个名字的概念了&#xff0c;这个就是开发嘛&#xff0c;不要过于纠结概念性东西。开发开发&#xff0c;开了就知道怎么发了&#xff1f; 或许是 反正write就…

基于虚拟阻抗的下垂控制——孤岛双机并联Simulink仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python3操作文件系列(二):文件数据读写|二进制数据读写

Python3操作文件系列(一):判断文件|目录是否存在三种方式 Python3操作文件系列(二):文件数据读写|二进制数据读写 Python3数据文件读取与写入 一: 文件数据|二进制数据读写 import os"""Python3的open(file,mode"文件的操作模式")利用该函数可以对…

基于腾讯云的OTA远程升级

一、OTA OTA即over the air,是一种远程固件升级技术&#xff0c;它允许在设备已经部署在现场运行时通过网络远程更新其固件或软件。OTA技术有许多优点&#xff0c;比如我们手机系统有个地方做了优化&#xff0c;使用OTA技术我们就不用召回每部手机&#xff0c;直接通过云端就可…

Git 学习笔记 | 版本控制和版本控制工具

Git 学习笔记 | 版本控制和版本控制工具 Git 学习笔记 | 版本控制和版本控制工具什么是版本控制&#xff1f;版本管理工具的特性版本管理工具的发展简史主流的版本控制器本地版本控制集中版本控制分布式版本控制 Git与SVN的主要区别 Git 学习笔记 | 版本控制和版本控制工具 学…

HttpClient实现爬虫开发

网络爬虫是一种高效获取网络信息的方式&#xff0c;而HttpClient是一个强大而灵活的Java库&#xff0c;提供了方便的API和丰富的功能&#xff0c;使其成为开发高效且灵活的网络爬虫的理想选择。本文将分享如何利用HttpClient库进行网络爬虫开发&#xff0c;帮助您更好地理解并实…

【计算机网络】因特网中的电子邮件

文章目录 简单邮件传送协议SMTP邮件访问协议POP3IMAPHTTP 参考资料 电子邮件为异步通信媒介 因特网电子邮件系统 电子邮件系统的三个构件&#xff1a;用户代理、邮件服务器、邮件发送和读取协议 用户代理 User Agent 即UA 电子邮件客户端软件&#xff0c;用户与电子邮件系统的接…

林沛满-TCP之在途字节数

本文整理自&#xff1a;《Wireshark网络分析的艺术 第1版》 作者&#xff1a;林沛满 著 出版时间&#xff1a;2016-02 我一直谨记斯蒂芬霍金的金玉良言—每写一道数学公式就会失去一半读者。不过为了深度分析网络包&#xff0c;有时候是不得不计算的&#xff0c;好在小学一年级…

图形学中一些基本知识的总结与复习

前言 在过完games101课程后仍然觉得自己还有许多地方不懂与遗漏&#xff0c;以此来补充与复习一些其中的知识。 参考&#xff1a;Games101、《Unity Shader 入门精要》 GPU渲染流水线(GPU Rendering Pipeline) ----注&#xff1a;Games101课程中所展示渲染流程与书中有所不同&…

javaWeb网上购物系统的设计与实现

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快&#xff0c;电子商务技术已经逐渐融入了人们的日常生活当中&#xff0c;网上商城作为电子商务最普遍的一种形式&#xff0c;已被大众逐渐接受。因此开发一个网上商城系统&#xff0c;适合当今形势&#xff0c;更加…

详解FreeRTOS:FreeRTOS任务恢复过程源码分析(进阶篇—4)

本篇博文讲解FreeRTOS中任务恢复过程的源代码,帮助各位更好理解恢复任务的原理和流程。 在详解FreeRTOS:FreeRTOS任务管理函数(基础篇—11)中,讲述了任务恢复函数有两个vTaskResume()和xTaskResumeFromISR(),一个是用在任务中的,一个是用在中断中的,但是基本的处理过程…

智慧空调插座:智控生活好伴侣,节能降耗好帮手

所谓“智能插座”&#xff0c;就是在普通插座上增加Wi-Fi模块&#xff0c;通过手机APP控制单个或整个插座的电源通断&#xff0c;并统计一段时间的用电量。 目前市面上所销售的智能插座&#xff0c;大多具备可连接Wi-Fi网路功能&#xff0c;如此一 来便不需要额外再购买定时控…

评价指标篇——IOU(交并比)

什么是IoU(Intersection over Union) IoU是一种测量在特定数据集中检测相应物体准确度的一个标准。 即是产生的候选框&#xff08;candidate bound&#xff09;与原标记框&#xff08;ground truth bound&#xff09;的交叠率 即它们的交集与并集的比值。最理想情况是完全重叠…

数据中台实战(11)-数据中台的数据安全解决方案

0 微盟删库跑路 除了快、准和省&#xff0c;数据中台须安全&#xff0c;避免“微盟删库跑路”。 2020年2月23日19点&#xff0c;国内最大精准营销服务商微盟出现大面积系统故障&#xff0c;旗下300万商户线上业务全停&#xff0c;商铺后台所有数据被清。始作俑者是一位运维&a…

秒验:可以自定义UI的一键登录服务

一键登录如今成为越来越多移动应用的首选&#xff0c;但千篇一律的登陆界面在引发用户担忧其安全性的同时&#xff0c;也容易让用户在不同APP切换时产生误解。因此&#xff0c;由国内知名移动应用开发服务商MobTech打造的一键登录工具——秒验&#xff0c;通过允许开发者自定义…

C#学习系列相关之多线程(一)----常用多线程方法总结

一、多线程的用途 在介绍多线程的方法之前首先应当知道什么是多线程&#xff0c; 在一个进程内部可以执行多个任务&#xff0c;而这每一个任务我们就可以看成是一个线程。是程序使用CPU的基本单位。进程是拥有资源的基本单位&#xff0c; 线程是CPU调度的基本单位。多线程的作用…

快速掌握批量合并视频

在日常的工作和生活中&#xff0c;我们经常需要对视频进行编辑和处理&#xff0c;而合并视频、添加文案和音频是其中常见的操作。如何快速而简便地完成这些任务呢&#xff1f;今天我们介绍一款强大的视频编辑软件——“固乔智剪软件”&#xff0c;它可以帮助我们轻松实现批量合…

C++深入学习part_1

Linux下编译C程序 安装g命令&#xff1a;sudo apt install g 编译命令&#xff1a;$ g *.cc 或者 *.cpp -o fileName; hellworld 编译程序可以看到&#xff1a; namespace命名空间 首先&#xff0c;命名空间的提出是为了防止变量重名冲突而设置的。 浅浅试一下&#xff1…

深度学习基础之参数量(3)

一般的CNN网络的参数量估计代码 class ResidualBlock(nn.Module):def __init__(self, in_planes, planes, norm_fngroup, stride1):super(ResidualBlock, self).__init__()print(in_planes, planes, norm_fn, stride)self.conv1 nn.Conv2d(in_planes, planes, kernel_size3, …

后端解决跨域(极速版)

header(Access-Control-Allow-Origin: *); header(Access-Control-Allow-Methods:*); 代表接收全部的请求&#xff0c;"POST,GET"//允许访问的方式 指定域&#xff0c;如http://172.20.0.206//宝塔的域名&#xff0c;注意不是&#xff1a;http://wang.jingyi.icu等…