JavaScript中跨域问题的深入理解


Posted in Javascript onMarch 04, 2021

前言:

学习JavaScript的童鞋都知道,我们在发送网络请求,也就是我们在地址栏输入一个网址,就会自动跳转到当前网址,比如在浏览器网址输入www.baidu.com,浏览器就会自动跳转到百度的的首页 而浏览器发送网络请求需要三和基本的要素

其实完整的url路径应该是:http://www.baidu.com:80浏览器在发送网络请求的时候回默认加上协议:http 和端口号80.
也就是完整的url至少 包含三个部分

1.http/https 传输协议

2.www.baidu.com 域名

3.80 端口号

因为有了这三个及基本要素,所以才有了所谓的跨域请求.那么什么是跨域请求呢,简单的说,跨域就是[传输协议 / 域名 / 端口号]有一个或者多个不相等时,此时就会触发浏览器的同源策略(同源,就是三者一样,属于同一源头),也就是跨域请求

补充:

- 同源策略是由浏览器给的

浏览器不允许我们向别人发送请求,只能向自己的服务器发送请求,当我们想向别人的服务器发送请求的时候,就会被浏览器阻止了

- 什么是 “别人的服务器” 呢?

当 请求协议/域名/端口号 有任意一个不同的时候,那么就算是别人的服务器这个时候就会触发同源策略

浏览器阻止我们去跨域(偷瞄别人的服务器),那我们自然也要大胆点,解决浏览器给的困难,也就是实现跨域请求.

在真实案例中,我们也会经常用到跨域请求,就比如我这个A网站,用到了B网站的美女图片,比较好的方法就是向B网站的服务器请求这些美女图片,也就是A网需要B网的数据,一旦这样子搞,就无形中形成了跨域请求.

**

那么如何实现跨域请求呢?

**

方法一:jsonp

学习jsonp技术之前我们现在了解一下,当我们通过script标签的src属性引入文件的时候,无论是什么文件类型,都会被解析成一段字符串,然后当做js代码执行.于是就可以使用这个巧妙的方法来实现跨域请求了,下面看案例.

假设我这里有一个a.text文件里面有一句代码

alert('a')

JavaScript中跨域问题的深入理解

我们去另一个网页引用这个a.text这个文件

JavaScript中跨域问题的深入理解

页面一打开,弹出了a ,说明a.text文件中的代码被执行了

JavaScript中跨域问题的深入理解

正是这样,我们是设想 假如我们请求的是服务器上的的文件呢,也不需要考虑它是什么后缀的,只要有返回值给我就行,那我在前端就可以拿到.于是,开始操作!

当我们去请求另一台服务器的数据时,比如!

http://10.36.136.96:80/ 是另一台服务器的地址

1.php 是另一台服务器上的文件,我们正常去请求

在另一台服务器上由一个文件叫 1.php

<script>
 //http://10.36.136.96:80/是另一台服务器的地址
 //1.php是另一台服务器上的文件,我们正常去请求

 var xhr = new XMLHttpRequest()
 xhr.open('get','http://10.36.136.96:80/1.php')
 xhr.onload = function () { 
 console.log(xhr.responseText);//1.php文件将要返回的结果
 }
 xhr.send()
 </script>

此时浏览器会报错如下错误,也就是触发了同源策略,出现了跨域请求

JavaScript中跨域问题的深入理解


此时我们就可以用到上面说到的script标签上的src属性,我们使用script去请求服务器上的文件

此时我们只要在json.html文件上写一行代码

<script src="http://10.36.136.96:80/1.php"></script>

可以看到浏览器没有报错,请求到了文件,并且拿到了内容,那么问题来了,我们怎么去拿到返回的结果呢?

这里就可以巧妙的运用一下回调函数.

JavaScript中跨域问题的深入理解

后端返回数据可以使用调用函数的方式来执行.

1.php文件后端的代码为

<?php

 $_GET['callback'];
 echo "$name('sanqian')";

?>

jsop.html文件前端代码为:

<script>
 function fn(data){
  console.log(data);
 }
 </script>
 <script src="http://10.36.136.96:80/1.php?callback=fn"></script>

callback 的=号后面的就是回调函数的名字,把它传递给1.php文件,在1.php文件就可以拿到这个,fn函数,调用传入讲到返回的数据,这样就可以在前端通过函数调用的方式轻松拿到.

也就是说我们在前端定义了一个全局函数,名为 fn 记住,一定是全局的函数, 函数名就是指向该函数的指针, 把函数名传过去, 后端拿到了,进行一番操作后 返回的是fn(‘sanqian'),而这个结果就会被拿到前端,当做js代码执行.也就说上面的代码等价于下面的代码

<script>
 function fn(data){
  console.log(data);
 }
 </script>
 <script>
 fn('sanqian')
 </script>

这样一来就是上面定义,下面执行调用,如此一来,就拿到了后端返回的结果.

JavaScript中跨域问题的深入理解

jsonp就是这么一个原理和使用方法,目前使用也是较为广泛的.要会的喔!

方法二: CROS

这是一个纯后端的方法,和前端没有任何关系.

当我们就真的傻乎乎去另一台服务器上请求数据的时候,浏览器就会有个经典的报错如下:

JavaScript中跨域问题的深入理解

翻译一下就是

JavaScript中跨域问题的深入理解

也就是访问被干掉了,我们需要吧请求的资源放在Access-Control-Allow-Origin标头上,

那么同样要返回结果[sanqian] , 然后我们的前后端代码就变成了下面这样

jsonp.html文件

<script>
 var xhr = new XMLHttpRequest()
 xhr.open('get','http://10.36.136.96:80/1.php')
 xhr.onload = function () { 
  console.log(xhr.responseText);
  }
  xhr.send()

1.php文件

<?php
 header('Access-Control-Allow-Origin:*');
 echo "sanqian";
?>

没错就是加上这么一行字,就可以正常请求到想要的资源了

当然也可以不止一行代码,还有一下的

//表明允许跨域访问
header(Access-Control-Allow-Origin:上面origin的地址)//*号代表所有
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE'); //支持的http 动作
header('Access-Control-Allow-Headers:x-requested-with,content-type'); //响应头 请按照自己需求添加

这个方法是跨域请求中最简单的方法了吧,还是后端的活.

方法三:服务器代理

proxy-代理

代理跨域(服务器正向代理跨域)因为浏览器不允许请求一个非同源地址

        在浏览器同源是何止一个代理服务器
        把本该发送给目标服务器的请求发送给代理服务器
        由代理服务器转发请求给目标服务器
        目标服务器把响应给代理服务器
        代理服务器再把响应给浏览器

只要是服务器就能进行代理,但是apache代理http的不需要花钱, https的需要花钱

nginxhttp和https都是免费的,所以使用nginx代理,也用nginx演示

我们首先需要在nginx服务器上配置好路径

JavaScript中跨域问题的深入理解

在配置文件的

servr{}里面

serve{
...
location = /sanqian {
	proxy_pass http://10.36.136.96:80/1.php;
	}
...
}

JavaScript中跨域问题的深入理解

配置好之后,jsonp.html文件的代码就变成了

<script>
 var xhr = new XMLHttpRequest()
 xhr.open('get','/sanqian') // 注意这里变了
 xhr.onload = function () { 
  console.log(xhr.responseText);
  }
  xhr.send()
 </script>

1.php文件代码变成了

<?php 
 echo "sanqian";
?>

/sanqian 就是我们本机服务器上要输上去的路径,当发现路径是/sanqian时,服务器就会发现,诶,原来你是想访问http://10.36.136.96:80/1.php这个地址,然后代理的服务器就去访问这个地址,拿到访问结果之后,在返回给当前去访问该地址的浏览器,这样就拿到了结果

JavaScript中跨域问题的深入理解

以上就是我对跨域请求的一些简单理解,可能写的不全或者缺错漏,如果发现,也请指出,谢谢!

总结

到此这篇关于JavaScript中跨域问题的文章就介绍到这了,更多相关JavaScript跨域问题内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Javascript 学习书 推荐
Jun 13 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
Mar 02 Javascript
JavaScript下通过的XMLHttpRequest发送请求的代码
Jun 28 Javascript
Jquery动态更改一张位图的src与Attr的使用
Jul 31 Javascript
window.onload追加函数使用示例
Mar 03 Javascript
javascript控制台详解
Jun 25 Javascript
JS实现图片垂直居中显示小结
Dec 13 Javascript
JS实现的全排列组合算法示例
Oct 09 Javascript
JS对日期操作封装代码实例
Nov 08 Javascript
Vue数据双向绑定底层实现原理
Nov 22 Javascript
vue项目启动出现cannot GET /服务错误的解决方法
Apr 26 Javascript
react antd实现动态增减表单
Jun 03 Javascript
vue3.0中使用element的完整步骤
Mar 04 #Vue.js
jQuery实现鼠标拖动图片功能
Mar 04 #jQuery
ajax jquery实现页面某一个div的刷新效果
Mar 04 #jQuery
jquery实现广告上下滚动效果
Mar 04 #jQuery
VUE实现吸底按钮
Mar 04 #Vue.js
vue实现可移动的悬浮按钮
Mar 04 #Vue.js
vue中axios封装使用的完整教程
Mar 03 #Vue.js
You might like
PHP控制网页过期时间的代码
2008/09/28 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
说说PHP的autoLoad自动加载机制
2012/09/27 PHP
深入理解PHP中的global
2014/08/19 PHP
PHP伪造来源HTTP_REFERER的方法实例详解
2015/07/06 PHP
Json_encode防止汉字转义成unicode的方法
2016/02/25 PHP
PHP微信开发之微信消息自动回复下所遇到的坑
2016/05/09 PHP
JavaScript Cookie的读取和写入函数
2009/12/08 Javascript
用Jquery实现可编辑表格并用AJAX提交到服务器修改数据
2009/12/27 Javascript
js 在定义的时候立即执行的函数表达式(function)写法
2013/01/16 Javascript
js图片延迟技术一般的思路与示例
2014/03/20 Javascript
PHP开发者必须掌握的6个关键字
2014/04/14 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
编写高质量JavaScript代码的基本要点
2016/03/02 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
实例详解display:none与visible:hidden的区别
2017/03/30 Javascript
express框架实现基于Websocket建立的简易聊天室
2017/08/10 Javascript
基于dataset的使用和图片延时加载的实现方法
2017/12/11 Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
2019/04/07 Javascript
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
原生javascript实现类似vue的数据绑定功能示例【观察者模式】
2020/02/24 Javascript
React+EggJs实现断点续传的示例代码
2020/07/07 Javascript
Python urllib模块urlopen()与urlretrieve()详解
2013/11/01 Python
Python统计日志中每个IP出现次数的方法
2015/07/06 Python
python中pandas.DataFrame排除特定行方法示例
2017/03/12 Python
[原创]pip和pygal的安装实例教程
2017/12/07 Python
Apache部署Django项目图文详解
2019/07/30 Python
python动态视频下载器的实现方法
2019/09/16 Python
Python小程序 控制鼠标循环点击代码实例
2019/10/08 Python
python 爬虫网页登陆的简单实现
2020/11/30 Python
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
11月升旗仪式讲话稿
2014/02/15 职场文书
2014年维修电工工作总结
2014/11/20 职场文书
任长霞观后感
2015/06/16 职场文书
导游词之南京栖霞山
2019/10/18 职场文书
html+css 实现简易导航栏功能
2021/04/07 HTML / CSS