5.nodejs--跨域、CORS、JSONP 、Proxy

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


1.跨域

(1.1) 跨域的基本概念

          如果用户访问我们的A服务器的网页,网页内部的AJAX去请求B服务器的数据接口,就算是B服务器、把json数据发送给了用户的浏览器,但是浏览器因为同源策略的原因,会阻止数据使用,这种现象就是跨域了。

        具体的跨域的两个服务器的标识是:协议 ip port

 (1)概念:浏览器为了用户的信息安全,网页中有一个网络请求技术:ajax在做网络请求时,请求的网址和当前页面的网址不是同一台服务器,就会被拒绝。
        跨域的两个条件:非同源 ajax

什么是同源策略
==>浏览器的一种安全策略,指两个网址的协议 ip port 三者一样代表同源

//同源==>pathname不参与同源判断
http://www.baidu.com/index.html
http://www.baiud.com/home/goods/ajax1

//异源 ==>域名(ip:port)不一样
http://www.hqyj.com/index.html
http://www.hqyj.con/ajax

//异源 ==>域名(ip:port)不一样
http://www.hqyj.com/index.html //假设解析DNS为192.168.6.86:8000
http://192.168.6.86:8000/ajax

(1.2) 接口的跨域问题

1.主要有两种方案:
        CORS(主流的解决方案,推荐使用)
        JSONP(有缺陷的解决方案:只支持GET请求)

    
2.使用cors中间件解决跨域问题
       使用步骤分为如下三步:
            (1) 运行npm install cors安装中间件
            (2) 使用const cors=require("cors")导入中间件
            (3) 在路由之前调用app.use(cors())配置中间件

2.CORS

(2.1)什么是cors,cors原理

  (1) 什么是cors?
     ==>   cors(跨域资源共享)由一系列http响应头组成,这些http响应头决定浏览器是否阻止前端js代码跨域获取资源
        浏览器的同源安全策略默认会阻止网页“跨域”获取资源,但如果接口服务器配置了cors相关的http响应头,就可以解除浏览器端的跨域访问限制。

cors的注意事项:
           (1) cors主要在服务器端进行配置,客户端浏览器无须做任何额外的配置,即可请求开启了cors的接口
            (2)cors在浏览器中由兼容性,只有支持XMLHttpRequest Level2的浏览器,才能正常访问开启了cors的服务器端接口。

  cors的原理:

         在实际生产或者项目的开发阶段,有时候真的需要跨域访问资源,可以在后端发送数据包时,在数据包的头部配置,这个数据包被跨域请求时的,跨域资源共享,白名单
          也就是:res.setHeader("Access-Control-Allow-Origin","具体的白名单域0,可以配置*")

(2.2) CORS跨域资源共享--CORS的三个响应头

(1)CORS响应头部--Access-Control-Allow-Origin

 (1) CORS响应头部--Access-Control-Allow-Origin
    响应头部中携带一个Access-Control-Allow-Origin字段,

        语法:Access-Control-Allow-Origin:<Origin>|*
    Origin参数的值指定了允许访问该资源的外域URL
   

 例如:下面的字段值将只允许来自http://itcast.cn的请求:
        res.setHeader('Access-Control-Allow-Origin','http://itcast.cn') 

(2)CORS响应头部--Access-Control-Allow-Headers  

 (2) CORS响应头部--Access-Control-Allow-Headers
        默认情况下,CORS仅支持客户端向服务器发送如下的9个请求头:
            Accep、tAccept-Language、 Content-Language 、DPR 、Downlink、 Save-Date、 Viewport-width 、width 、Content-Type、(值仅限于text/plain、 mulitport/form-data、 application/x-www-form-urlencoded三者之一)
        如果客户端向服务器发送了额外的请求头消息,则需要在服务器端,通过Access-Control-Allow-Headers对额外的请求头进行声明,否则这次请求会失败

例如:
res.setHeader('Access-Control-Allow-Headers','Content-Type','X-custom-Headers')

(3) CORS响应头部--Access-Control-Allow-Methods

  (3) CORS响应头部--Access-Control-Allow-Methods
        默认情况下,CORS仅支持客户端发起GET POST HEAD请求
        如果客户端希望通过PUT DELETE等方式请求服务器的资源,则需要在服务器端,通过Access-Control-Allow-Methods来指明实际请求所允许使用的HTTP方法。
        示例如下:
           

 //允许所有的HTTP请求方法:
    res.setHeader('Access-Control-Allow-Methods','*')
//只允许POST GET DELETE HEAD请求方法:
    res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,HEAD')

(2.3)CORS请求的分类

  客户端在请求CORS请求时,根据请求方式和请求头的不同,可以将CORS的请求分为两大类:
        (1)简单请求
            (1)请求方式:GET POST HEAD三者之一
            (2)HTTP头部信息不超过以下几种字段:无自定义头部字段、Accept、 Accept-Language、 Content-Language 、DPR 、Downlink 、Save-Date 、Viewport-width、 width、 Content-Type、(只有三个值text/plain、 mulitport/form-data、 application/x-www-form-urlencoded)
        (2)预检请求
            (1)请求方式为GET POST HEAD之外的请求Method类型
            (2)请求头中包含自定义头部字段
            (3)向服务器发送了application/json格式的数据
        在浏览器于服务器正式通信之前,浏览器会先发送OPTION请求进行预测,以获知服务器是否允许该实际请求,所以这一次的OPTION请求称为"预检请求"
        服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。

简单请求和预检请求的区别
    简单请求的特点:客户端和服务器之间只会发生一次请求
    预检请求的特点:客户端和服务器之间会发生两次请求,OPTION预检请求成功之后,才会发起真正的请求。

3.JSONP

(3.1)JSONP的概念以及特点

JSONP接口
    JSONP概念:浏览器通过<script>标签的src属性,请求服务器上的数据,同时,服务器返回一个函数的调用,这种请求数据的方式叫做JSONP

特点:
        JSONP不属于真正的Ajax请求,因为它没有XMLHttpRequest这个对象
        JSONP仅支持GET请求,不支持POST PUT DELETE等请求。


    创建JSONP接口的注意事项
        如果在项目中已经配置了CORS跨域资源共享,为了防止冲突,必须配置CORS中间件之前声明JSONP接口,否则JSONP接口会被处理成CORS的接口。
       

 例如:  
                //优先创建JSONP接口
            app.get('/api/jsonp',(req,res)=>{})
                //在配置CORS中间件
            app.use(cors())
                //这是一个开启了的CORSS接口
            app.get('/api/get',(req,res)=>{})

(3.2) 实现JSONP接口的步骤

(3.2) 实现JSONP接口的步骤
        (1)获取客户端发送过来的回调函数的名字
        (2)得到要通过JSONP形式发送给客户端的数据
        (3)根据前两步得到的数据,拼接出一个函数调用的字符串
        (4)把上异步拼接得到的字符串,响应给客户端的<script>标签进行解析执行。

    具体代码示例:
     

  app.get('/api/jsonp',(req,res)=>{
                //1.获取客户群发送过来的回调函数的名字
            const funcName=req.query.callback

                //2.得到要通过JSONP形式发送给客户端的数据
            const data={name:'zs',age:22}

                //3.根据前两步得到的数据,拼接出一个函数调用的字符串
            const scriptStr=`${funcName}({JSON.stringify(data)})`

                //4.把上异步拼接得到的字符串,响应给客户端的<script>标签进行解析执行。
            res.send(scriptStr)
        })

在网页中使用jQuery发起JSONP请求
        调用$.ajax()函数,提供JSONP的配置选项,从而发起JSONP请求,示例代码如下:
     

  //为JSONP按钮绑定点击事件处理函数
        $("#btnJSONP").on('click',function(){
            $.ajax({
                method:'GET',
                URL:'http://127.0.0.1/api/jsonp',
                dataType:'jsonp',
                success:function(res){
                    console.log(res)
                }
            })
        })

(3.3)讲一讲你对JSONP的理解?

1.前端网页中用ajax请求跨域服务器的网址  会报跨域错误

    用script标签的src属性去请求跨域服务器的网址 不会报跨域错误,但是 会直接把请求过来的编码用v8引擎去运行

   

2. 我们可以在后端写一个js引擎能识别的字符串发送给前端,这个字符串是这样的:

    ' fn({"name":"karen"}) '

前端可以用script标签的src属性去请求这个网址,请求完毕以后 v8就会直接运行这个编码 去调用fn函数,所以我们必须提前创建这个函数

   

3.函数的名称问题:  前端可以通过querystring把函数名以参数的形式发送给后端

    后端解析了以后 直接拼接到数据中(比如那个fn)

(3.4)JSONP原理

 前端设置一个函数假设函数名为fn1,然后把fn1这个字符串用script标签的src属性发送给后端,后端解析出参数querystring中的fn1字符串,把后端的json数据拼接成‘fn1(json数据)’这个字符串,前端是因为是用的script请求的资源因此:不会有跨域限制,并且会把得到的资源用v8去运行,然后就会执行,提前设定好的函数fn1就可以接收到网络请的数据,这种利用了script去跨域请求的设计就是JSONP。

4.Proxy

(4.1)Proxy原理

    在开发阶段,最常用的手段,比如vue,react,等前端框架中
    常常有一个自己的开发服务器
    如果用户访问我们的A服务器的网页,网页内部的AJAX去请求B服务器的数据接口,是不会跨域的
    然后A服务器去请求B服务器的数据,再把返回给A服务器的数据,返回的用户
    A服务器就是一个代理服务器。

核心代码:
var router=require("./router.js")
var request=require("request")//是一个后端的网络请求工具

router.get("/home",function(req,res){
	request("http://www.baidu.com/index.html",function(agr1,arg2,arg3){
		res.end(arg3)
	})
	
	  
})

   钓鱼网站--违法

            前端请求后端

            后端请别的网页数据 然后修改了 发给用户

      

    大数据分析

            后端请别的ajax网址数据  数据处理 发给用户   

     

     爬虫--灰色

             后端请别的静态文件和数据  数据处理 发给用户

     

     Proxy 代理服务

             后端合法的去请求别的后端(oAuth授权-token)  再发给前端 前端写成自己的页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值