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权威指南 学习笔记之null和undefined
Sep 25 Javascript
JS记录用户登录次数实现代码
Jan 15 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
May 09 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
Jun 03 Javascript
JS组件Bootstrap Table表格多行拖拽效果实现代码
Dec 08 Javascript
微信小程序开发之animation循环动画实现的让云朵飘效果
Jul 14 Javascript
node.js express中app.param的用法详解
Jul 16 Javascript
浅谈angular4 ng-content 中隐藏的内容
Aug 18 Javascript
ajax+node+request爬取网络图片的实例(宅男福利)
Aug 28 Javascript
利用angular、react和vue实现相同的面试题组件
Feb 19 Javascript
jquery无缝图片轮播组件封装
Nov 25 jQuery
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 07 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
比较strtr, str_replace和preg_replace三个函数的效率
2013/06/26 PHP
phpStudy 2016 使用教程详解(支持PHP7)
2017/10/18 PHP
JS判断页面加载状态以及添加遮罩和缓冲动画的代码
2012/10/11 Javascript
jquery 循环显示div的示例代码
2013/10/18 Javascript
Javascript 按位取反运算符 (~)
2014/02/04 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
jQuery入门基础知识学习指南
2015/08/14 Javascript
谈谈我对JavaScript中typeof和instanceof的深入理解
2015/12/25 Javascript
JS针对浏览器窗口关闭事件的监听方法集锦
2016/06/24 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
2017/04/11 Javascript
angular6.0使用教程之父组件通过url传递id给子组件的方法
2018/06/30 Javascript
详解node.js的http模块实例演示
2018/07/12 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
jquery中为什么能用$操作
2019/06/18 jQuery
vue+springboot+element+vue-resource实现文件上传教程
2020/10/21 Javascript
[20:39]DOTA2-DPC中国联赛 正赛开幕式 1月18日
2021/03/11 DOTA
python轻松查到删除自己的微信好友
2016/01/10 Python
Python计算两个日期相差天数的方法示例
2017/05/23 Python
Python实现的十进制小数与二进制小数相互转换功能
2017/10/12 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
Python中单例模式总结
2018/02/20 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
IE8下CSS3选择器nth-child() 不兼容问题的解决方法
2016/11/16 HTML / CSS
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
波兰办公用品和学校用品在线商店:Dlabiura24.pl
2020/11/18 全球购物
方正Java笔试题
2014/07/03 面试题
传媒专业推荐信范文
2013/11/23 职场文书
学生打架检讨书1000字
2014/01/16 职场文书
中专毕业生个人职业生涯规划
2014/02/19 职场文书
国贸专业自荐信范文
2014/03/02 职场文书
计划生育标语
2014/06/23 职场文书
导游词之湖北梁子湖
2019/11/07 职场文书