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

同源和跨域详解_如何实现跨域同源同源策略的基本概念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,如果没有服务端的允许,浏览器是没法做到跨域的。

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

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

(0)
上一篇 2022年8月2日 下午10:00
下一篇 2022年8月2日 下午10:16


相关推荐

  • Java WeakHashMap

    Java WeakHashMap作为一个java开发者肯定都知道且使用HashMap,但估计大部分人都不太知道WeakHashMap。从类定义上来看,它和普通的HashMap一样,继承了AbstractMap类和实现了Map接口,也就是说它有着与HashMap差不多的功能。那么既然jdk已经提供了HashMap,为什么还要再提供一个WeakHashMap呢?黑格尔曾经说过,存在必合理,接下来我们来看下为什么有WeakHashM…

    2022年5月31日
    35
  • eplan激活码大全-激活码分享2022.01.21

    (eplan激活码大全)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月31日
    257
  • python中的eval函数的用法_isnan函数

    python中的eval函数的用法_isnan函数eval函数在Python中具有非常重要的地位,熟练的使用eval函数能够为我们的Python编程提供很多的便利之处。在本文中我将详细记录eval函数在Python中的使用方法及它带来便利时带来的一些其他危害,希望您阅读完本文后能够有所收获。欢迎在文章下方留言共同交流学习。

    2025年8月12日
    4
  • 无线通信——基于MATLAB实现OFDM系统(信道估计与均衡)

    无线通信——基于MATLAB实现OFDM系统(信道估计与均衡)基于 MATLAB 实现 OFDM 系统基带信号在频率选择性衰落信道条件下的发送与接收题目及要求 仿真系统构成 信号输入 为随机比特流 OFDM 调制 仿真信道传输 OFDM 解调 信号输出 可能存在误码的比特率 仿真分析内容 根据输入 输出比特流计算不同信噪比条件下的误码率 并绘制曲线 对调制的要求 OFDM 调制的子载波间隔为 15KHz 循环前缀长度及子载波数目可调 各子载波使用 QPSK 调制 其它要求 信道采用 3GPPTS36 101 给出的 ETU300Hz 多径信道 并在其上叠加一个信噪比可调的白噪

    2026年3月17日
    1
  • 成为黑客需要学习什么技能?

    成为黑客需要学习什么技能?1.学习如何编程这当然是最基本的黑客技能。如果你还不会任何编程语言,我建议你从Python开始。它设计清晰,文档齐全,合适初学者入门。它是一门很好的入门语言,并且不仅仅只是个玩具;它非常强大、灵活,也适合做大型项目。我有一篇Python评价详细说明这点。好的教程可以在Python网站得到。Java也是好的入门语言。它比Python难得多,但是生成的代码速度也快得…

    2025年12月14日
    7
  • 嵌入式C语言面试题_c语言基础面试题

    嵌入式C语言面试题_c语言基础面试题预处理器(Preprocessor)1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)         #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL我在这想看到几件事情:1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何…

    2022年8月27日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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