同源和跨域详解_如何实现跨域

同源和跨域详解_如何实现跨域同源同源策略的基本概念1995年,同源政策由Netscape公司引入浏览器。目前,所有浏览器都实行这个政策。同源策略:最初,它的含义是指,A网页设置的Cookie,B网页不能打开,除非这两个

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

同源

同源策略的基本概念

1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。所谓”同源”指的是”三个相同”。


协议相同
域名相同
端口相同

举例来说,这个网址http://www.example.com/dir/page.html协议是http://

域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。


http://www.example.com/dir2/other.html:同源

file:///F:/phpStudy/WWW/day01/04-demo/04.html 不同源(协议不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)

同源策略的目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

同源策略的限制范围

随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。


1. Cookie、LocalStorage IndexDB 无法读取。
2. DOM 无法获得。
3. AJAX 请求在浏览器端有跨域限制

虽然这些限制是很有必要的,但是也给我们日常开发带来不好的影响。比如实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域 。

跨域

jsonp( 无兼容性问题 )

JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。

原理:服务端返回一个定义好的js函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合

script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件。类似的还有imglink标签


<!--不受同源策略限制的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>

 

jsonp演化过程1

php文件


header("content-type:text/html;charset=utf-8");
echo "alert(1111)";

html文件


<script src="http://www.api.com/testjs.php"></script>

原理:其实src的路径是什么文件不重要,无论引入js文件还是php文件,最后返回给浏览器的都是字符串,因此我们script标签是可以引入一个php文件的。

 

jsonp演化过程2

php文件


header("content-type:text/html;charset=utf-8");
echo "var a = 118;";

html文件


<script src="http://www.api.com/testjs.php"></script>
<script>
 //a打印出来了118
 console.log(a);
</script>

我们现在做到了一件事情,从不同源的php文件中获取到了数据

 

缺点:获取数据的script标签必须写在使用的script标签的前面,必须保证先有数据才能对数据进行渲染。

 

jsonp演化过程3

php代码


header("content-type:text/html;charset=utf-8");
$arr = array(
   "name"=>"zs",
   "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo "func($result)";

js代码


<script>
 function func(data) {
   console.log(data);
}
</script>
<script src="http://www.api.com/testjs.php"></script>

 

缺点:后端必须知道前端声明的方法的名字,后端才能调用。

 

jsonp演化过程4

php代码


header("content-type:text/html;charset=utf-8");
$arr = array(
   "name"=>"zs",
   "age"=>18
);
$result = json_encode($arr);
//这是一段js函数的调用的代码,$result就是我们想要的数据
echo $_GET['callback']."($result)";

javascript代码


function fun(data) {
 console.log(data);
}
var button = document.querySelector("button");
button.onclick = function () {
 var script = document.createElement("script");
 script.src = "http://www.api.com/testjs.php?callback=fun";
 document.body.appendChild(script);
}

 

  1. 说白了,jsonp的原理就是 借助了script标签 src 请求资源时, 不受同源策略的限制.

  2. 在服务端返回一个函数的调用,将数据当前调用函数的实参。

  3. 在浏览器端,需要程序要声明一个全局函数,通过形参就可以获取到服务端返回的对应的值

 

jsonp原理大家需要知道,但不用太过于去纠结这个原理,因为jquery已经帮我们封装好了,我们使用起来非常的方便。

jquery对于jsonp的封装


//使用起来相当的简单,跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
$.ajax({
 type:"get",
 url:"http://www.Jepson.com/testjs.php",
 dataType:"jsonp",
 data:{
   uname:"Jepson",
   upass:"123456"
},
 success:function (info) {
   console.log(info);
}
});

XMLHttpRequest2.0

XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。

老版本的XMLHttpRequest的缺点:


1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
2. 传输数据时,没有进度信息,只能提示完成与否。
3. 受到了"同源策略"的限制

 

新版本的功能:


1. 可以设置timeout超时时间
2. 可以使用formData对象管理表单数据
3. 允许请求不同域名下的数据(跨域)
4. 支持上传二进制文件
5. 可以获取数据传输的进度信息

timeout设置超时


xhr.timeout = 3000;//设置超时时间
xhr.ontimeout = function(){
 alert("请求超时");
}

formData管理表单数据

formData对象类似于jquery的serialize方法,用于管理表单数据


使用特点:
1. 实例化一个formData对象, new formData(form); form就是表单元素
2. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
3. formData有一个append方法,可以添加参数。formData.append("id", "1111");
4. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。

 

代码示例:


//1. 使用formData必须发送post请求
   xhr.open("post", "02-formData.php");
   
//2. 获取表单元素
var form = document.querySelector("#myForm");
//3. 创建form对象,可以直接作为send的参数。
var formData = new FormData(form);

//4. formData可以使用append方法添加参数
formData.append("id", "1111");

//5. 发送,不需要指定请求头,浏览器会自动选择合适的请求头
xhr.send(formData);

 

文件上传

以前,文件上传需要借助表单进行上传,但是表单上传是同步的,也就是说文件上传时,页面需要提交和刷新,用户体验不友好,xhr2.0中的formData对象支持文件的异步上传。


var formData = new FormData();
//获取上传的文件,传递到后端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);

 

显示文件进度信息

xhr2.0还支持获取上传文件的进度信息,因此我们可以根据进度信息可以实时的显示文件的上传进度。


1. 需要注册 xhr.upload.onprogress = function(e){} 事件,用于监听文件上传的进度.注意:需要在send之前注册。
2. 上传的进度信息会存储事件对象e中
3. e.loaded表示已上传的大小   e.total表示整个文件的大小

 

代码参考:


xhr.upload.onprogress = function (e) {
 
 inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
 span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}

xhr.send(formData);

如果上传文件超过8M,php会报错,需要进行设置,允许php上传大文件。

同源和跨域详解_如何实现跨域

 

跨域资源共享(CORS) ( 兼容性IE10+ )

cors的使用

新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做“跨域资源共享”(Cross-origin resource sharing,简称CORS)。

跨域资源共享(CORS)的前提

  • 浏览器支持这个功能( 兼容性IE10+ )

  • 服务器必须允许这种跨域。

服务器允许跨域的代码:


//允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");
//允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");

 

CORS的具体流程(了解)

  1. 浏览器发送跨域请求

  2. 服务器端收到一个跨域请求后,在响应头中添加Access-Control-Allow-Origin Header资源权限配置。发送响应

  3. 浏览器收到响应后,查看是否设置了header('Access-Control-Allow-Origin:请求源域名或者*');

    如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

结论:

  1. 跨域行为是浏览器行为,响应是回来了的, 只是浏览器安全机制做了限制, 对于跨域响应内容进行了忽略。

  2. 服务器与服务器之间是不存在跨域的问题的

 

jsonp与cors的对比

  • jsonp兼容性好,老版本浏览器也支持,但是jsonp仅支持get请求,发送的数据量有限。使用麻烦

  • cors需要浏览器支持cors功能才行。但是使用简单,只要服务端设置允许跨域,对于客户端来说,跟普通的get、post请求并没有什么区别。

  • 跨域的安全性问题:因为跨域是需要服务端配合控制的 ,也就是说不论jsonp还是cors,如果没有服务端的允许,浏览器是没法做到跨域的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/167775.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • springEL表达式_Spring详解

    springEL表达式_Spring详解文章目录SpEL表达式SpEL表达式概述1、什么是SpEL表达式2、SpEL表达式的作用SpEL的使用方式1、xml配置的方式2、注解的方式SpEL表达式的调用SpEL表达式SpEL表达式概述1、什么是SpEL表达式SpEL:(springexpressionlanguage)是一种表达式语言,是一种强大,简洁的装配Bean的方式。他可以通过运行期间执行的表达式将值装配到我们的…

  • Java8新特性 stream流常用方法

    Java8新特性 stream流常用方法Java8API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。StreamAPI可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,…

  • ideal21激活码(JetBrains全家桶)

    (ideal21激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~ML…

  • 数字信号处理频谱分析实验_声压频谱分析仪软件

    数字信号处理频谱分析实验_声压频谱分析仪软件从实验室到现场进行测量当今的无线信号环境比以往任何时候都要复杂。面对迅速的创新,新的无线信号标准以及不断增长的频率和带宽要求,研究人员必须找到新的方法来检测RF干扰,分类信号类型,测试传播模型并确保在各种环境中的覆盖范围。他们需要一种经济高效,通用且可联网的替代方案,以替代传统的基于硬件的频谱分析设备。为了在真实条件下进行实验并验证仿真或模型,这些频谱分析解决方案必须能够在实验室和现场中部署,并与通用实验室软件和处理工具集成在一起,以进行更深入的信号分析。应用与要求无线研究人员需要的解决方案是

  • qmake自定义函数「建议收藏」

    qmake自定义函数「建议收藏」使用qmake编写构建步骤时,如果较为复杂或重复的行为可以使用函数来实现。

  • matplotlib-bilibili,抖音很火的动态数据视频自动生成(第四节)-视频,语音合成

    matplotlib-bilibili,抖音很火的动态数据视频自动生成(第四节)-视频,语音合成

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号