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 相关文章推荐
判断是否输入完毕再激活提交按钮
Jun 26 Javascript
js 去除字符串第一位逗号的方法
Jun 07 Javascript
jQuery 重复加载错误以及修复方法
Dec 16 Javascript
javascript的switch用法注意事项分析
Feb 02 Javascript
JavaScript实现将xml转换成html table表格的方法
Apr 17 Javascript
详解WordPress开发中get_current_screen()函数的使用
Jan 11 Javascript
Input文本框随着输入内容多少自动延伸的实现
Feb 15 Javascript
基于vue开发的在线付费课程应用过程
Jan 25 Javascript
JS实现十分钟倒计时代码实例
Oct 18 Javascript
vue如何获取自定义元素属性参数值的方法
May 14 Javascript
JS中的模糊查询功能
Dec 08 Javascript
浅谈JavaScript窗体Window.ShowModalDialog使用
Jul 22 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学习笔记之数组篇
2011/06/28 PHP
PHP中常用的转义函数
2014/02/28 PHP
php求正负数数组中连续元素最大值示例
2014/04/11 PHP
thinkPHP5.0框架API优化后的友好性分析
2017/03/17 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
利用Ext Js生成动态树实例代码
2008/09/08 Javascript
JQUBAR1.1 jQuery 柱状图插件发布
2010/11/28 Javascript
jQuery 数据缓存模块进化史详细介绍
2012/11/19 Javascript
Egret引擎开发指南之编译项目
2014/09/03 Javascript
JavaScript sup方法入门实例(把字符串显示为上标)
2014/10/20 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
2016/04/07 Javascript
jQuery中使用animate自定义动画的方法
2016/05/29 Javascript
基于Vue过渡状态实例讲解
2017/09/14 Javascript
Vue实现用户自定义字段显示数据的方法
2018/08/28 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
使用JavaScript获取Django模板指定键值数据
2020/05/27 Javascript
JavaScript前端开发时数值运算的小技巧
2020/07/28 Javascript
Python的SQLAlchemy框架使用入门
2015/04/29 Python
Python中处理字符串之endswith()方法的使用简介
2015/05/18 Python
Python实现LRU算法的2种方法
2015/06/24 Python
python控制台中实现进度条功能
2015/11/10 Python
Python反射用法实例简析
2017/12/22 Python
利用Python进行图像的加法,图像混合(附代码)
2019/07/14 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
python微信公众号开发简单流程实现
2020/03/09 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
2020/05/11 Python
介绍CSS3使用技巧5个
2009/04/02 HTML / CSS
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
CLR与IL分别是什么含义
2016/08/23 面试题
计算机专业优秀大学生自我总结
2014/01/21 职场文书
优秀经理事迹材料
2014/02/01 职场文书
党的群众路线教育实践活动心得体会900字
2014/03/07 职场文书
勤俭节约主题班会
2015/08/13 职场文书
《莫泊桑拜师》教学反思
2016/02/22 职场文书
django上传文件的三种方式
2021/04/29 Python
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL