同源策略

首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个域加载的脚本去获取另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。

js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据。

只要协议、域名、端口有任何一个不同,都被当作是不同的域。

下面介绍几种常用的跨域请求方式

默认端口为:8080

一、利用jQuery获取jsonp

JSONP的原理与实现思路

1)Web页面调用js文件,可跨域。扩展:但凡有src属性的标签都具有跨域能力。
2)跨域服务器 动态生成数据 并存入js文件(通常json后缀),供客户端调用。
3)为了便于客户端使用数据,形成一个非正式传输协议,称为JSONP。该协议重点是允许用户传递一个callback参数给服务器,然后服务器返回数据时 将此callback参数作为函数名包裹住JSON数据,使得客户端可以随意定制自己的函数来自动处理返回数据。

 1.1如果我们不用跨域请求的写法的话:

$('#cors1').click(function() {$.ajax({type:'get',url:'http://localhost:8081/girl/hello/say',success:function(data) {console.log(data);}})
});

1.2使用跨越请求的写法,最简单的就是设置dataType:jsonp:

jsonp指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个callback=xxx,xxx是jquery随机生成的一个回调函数名称。

这里的success默认success()作为回调函数。数据返回到前端后,就是success(result)的形式,因为是script脚本,所以自动调用success函数,而result就是success的参数。

$('#cors1').click(function() {$.ajax({type:'get',dataType:'jsonp',url:'http://localhost:8081/girl/hello/say',success:function(data) {console.log(data);}})
});

    @RequestMapping(value="/say", method =RequestMethod.GET)      //后端代码public String say(@RequestParam("callback") String callback){//callback前端传过来的回调函数名称//数据String result = "{age:22}";//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了result = callback + "(" + result + ")";returnresult;}

1.3jsonpCallback

为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。

调用回调函数的时候,先调用了指定的showData,然后再调用了success。

$('#cors1').click(function() {$.ajax({type:'get',dataType:'jsonp',   //指定服务器返回的数据类型 jsonpCallback:'showData',    //指定回调函数名称url:'http://localhost:8081/girl/hello/say',success:function(data) {console.log(data);}})
});functionshowData(data) {console.log("show"+data);
}

1.4jsonp

在一个jsonp请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

$('#cors1').click(function() {$.ajax({type:'get',dataType:'jsonp',jsonpCallback:'showData',jsonp:'sendParam',  //指定参数名称url:'http://localhost:8081/girl/hello/say',success:function(data) {console.log(data);}})
});functionshowData(data) {console.log(data);
}

指定jsonp后,后端也要改变:

    @RequestMapping(value="/say", method =RequestMethod.GET)public String say(@RequestParam("sendParam") String sendParam){//sendParam前端传过来的回调函数名称//数据String result = "{age:22}";//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了result = sendParam + "(" + result + ")";returnresult;}

1.5jsonp方式不支持POST方式跨域请求,就算指定成POST方式,会自动转为GET方式;而后端如果设置成POST方式了,那就请求不了了。

二、设置CORS头“Access-Control-Allow-Origin”

  • CORS的原理:
CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。
$('#cors1').click(function() {$.ajax({type:'get',url:'http://localhost:8081/girl/hello/say',success:function(data) {console.log(data);}})
});

    @RequestMapping(value="/say", method =RequestMethod.GET)publicString say(HttpServletRequest request, HttpServletResponse response){//设置响应头response.setHeader("Access-Control-Allow-Origin","*");  //当前我设置的header为“*”,任意一个请求过来之后服务端我们都可以进行处理&响应
    // 指定特定域名可以访问response.setHeader("Access-Control-Allow-Origin", "http:localhost:8080/")
//数据String result = "{age:22}";returnresult;}

三、iframe+window.postMessage实现跨域

script、image、iframe的src都不受同源策略的影响。所以我们可以借助这一特点,实现跨域。

postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

发送消息

postMessage(data,origin)方法接受两个参数

1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。

2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

<iframeid="ifr"src="http://localhost:8081/girl/b.html"></iframe>

window.onload = function() {var ifr = document.getElementById("ifr");ifr.contentWindow.postMessage("crsf","http://localhost:8081");
};

接收消息

<!DOCTYPE html>
<htmllang="en">
<head><metacharset="UTF-8"><title>testb</title>
</head>
<body><div>b</div>
</body>
</html>
<script>
window.addEventListener('message', function(event){    console.log('origin: '+event.origin);    //origin: http://localhost:8080    console.log('data: '+event.data);      //data: crsf    console.log(event.source);    // 回发数据    event.source.postMessage('hello world', event.origin);});
</script>

有几个重要属性

  1. origin:发送消息窗口的源(协议+主机+端口号)
  2. data:顾名思义,是传递来的message
  3. source:发送消息的窗口对象

这样就可以接收跨域的消息了,我们还可以发送消息回去。

转载于:https://www.cnblogs.com/chaixiaozhi/p/8545462.html

跨域请求的常用方式及解释相关推荐

  1. jQuery中Ajax+Spring MVC实现跨域请求

    项目开发中,某个可独立.也可集成的子业务模块须要向外开放相关API接口,先说下项目本身使用了jersery来实现RESTful webservice以名词形式公布API.有意思的是在实际的操作中同事却 ...

  2. php 跨域读php_php跨域的几种方式

    PHP实现跨域的几种形式 1.JSONP(JSON with padding)原理 利用html里面script标签可以加载其他域下的js这一特性,使用script src的形式来获取其他域下的数据, ...

  3. 【springboot】【若依(ruoyi)】@RestController 接口跨域请求

    前言 springboot 2.1.1.RELEASE 360极速浏览器 12.0.1476.0 (正式版本) (32 位) jquery 3.5.0 接口跨域请求有两者方式: jsonp CORS ...

  4. axios跨域请求的qs用法 - qs安装篇

    axios跨域请求的qs用法,本文说明如何安装qs vue项目跨域请求post提交方式:先npm install qs --save-dev cmd安装指令: npm install qs 运行安装的 ...

  5. AJAX跨域请求的理解,JAVA

    引至:https://www.cnblogs.com/zifayin/p/7338423.html 1.浏览器的同源策略 目前所有浏览器都由同源策略 什么是同源策略:      协议.域名.端口都一直 ...

  6. ajax 跨域请求数据,JQuery Ajax执行跨域请求数据的解决方案

    JQuery Ajax执行跨域请求数据的解决方案 今天前端因为需要ajax调用两个不同的项目,请求域不一样,所以涉及ajax跨域的问题 ,其实很简单,具体如下 原来的ajax请求如下: $.ajax( ...

  7. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...

  8. 第四节:跨域请求的解决方案和WebApi特有的处理方式

    一. 简介 前言: 跨域问题发生在Javascript发起Ajax调用,其根本原因是因为浏览器对于这种请求,所给予的权限是较低的,通常只允许调用本域中的资源, 除非目标服务器明确地告知它允许跨域调用. ...

  9. 第十八节:跨域请求的解决方案和WebApi特有的处理方式

    一. 简介 前言: 跨域问题发生在Javascript发起Ajax调用,其根本原因是因为浏览器对于这种请求,所给予的权限是较低的,通常只允许调用本域中的资源, 除非目标服务器明确地告知它允许跨域调用. ...

最新文章

  1. linux shell sed命令 在文本每行 行尾 或 行首 添加字符
  2. Ubuntu下eclipse indigo版在线安装struts插件
  3. 2021年下半年软考报考流程!
  4. Vivado simulation使用简介
  5. 鸿蒙 体验,华为鸿蒙OS全面上线,实际体验更胜EMUI11,安卓迎来“对手”
  6. 第六章 数组和索引器 (6.6 索引器)
  7. vue 特定条件下绑定事件
  8. Mac 下nginx 环境的配置
  9. 按新的退休年龄计算,64年的职工应该是哪年退休呢?
  10. rk修改launcher_RK launcher V 0.41 官方版
  11. Window API 第五篇 WTSEnumerateProcesses
  12. Scheme 协议收集总结
  13. Android VideoView播放avi格式视频有声音无图像问题
  14. 建站html代码,HTML代码大全
  15. 关于机械系2011年硕士生复试有关事…
  16. VR全景拍摄如何拍摄?如何使用拍摄器材?
  17. Python实现微信祝福语自动发送
  18. plt保存图像、去白边、去坐标轴、去刻度
  19. gitlab安装和汉化
  20. 大数据面试之kafka重点(二)

热门文章

  1. enum ordinal java_Java中怎样由枚举常量的ordinal值获得枚举常量对象
  2. 蓝桥集训之BFS、DFS和链式前向星
  3. Recorder︱图像语义分割(FCN、CRF、MRF)、论文延伸(Pixel Objectness、)
  4. [linux] redhat 7 iptables 配置
  5. cocos2d JS 鼠标响应事件
  6. ym——物联网入口之中的一个Android蓝牙4.0
  7. SaaS产品服务进行网络推广的必要性
  8. php模拟post提交
  9. boost中的mutex与lock
  10. 如何循序渐进向DotNet架构师发展(转,写的不错)