解决跨域访问

同源策略

由Netscape公司引入浏览器。目前,所有浏览器都实行这个政策。

目的是为了保证用户信息的安全,防止恶意的网站窃取数据


若非同源,会有三种行为限制:
1、Cookie、LocalStorage和indexDB无法读取
2、DOM无法获得
3、AJAX请求不能发送


同源指的是:协议相同、域名相同、以及端口相同。


互联网默认原则(不允许跨域访问)

常见跨域

HTML 页面中一些允许指定路径的元素具有跨域特性:

<link>元素
<script>元素
<img>元素
<iframe>元素

解决跨域

CORS(后端操作)
跨域是前端工作中不可避免的问题:我们经常会出现请求不同源接口的情况,为了能够获取数据,解决跨域的问题方案也有很多,但是常用的就两种

■第一种: CORS(后端操作)
目前的主流方案,也是最简单的方案,直接让后端设置响应头,允许资源共享就ok.


跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器  让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

例如:

app.get('/login',(req,res)=>{
    //设置响应头,允许资源被访问/共享
    res.setHeader('Access-Control-Allow-Origin','*')
    /*表示所有请求路径都可以请求这个接口*/
})


解决跨域问题,设置响应头的代码,可以在中间件中写,这样可以在所有接口中都会应用到(只在中间件写一次就可以了,不用再多个接口中去写,因为中间件是在服务器开启之后和路由响应之前执行的一个函数)

例如:

app.use((req,res,next)=>{
     //在中间件中设置响应头,允许资源被所有接口访问/共享
    res.setHeader('Access-Control-Allow-Origin','*')
    next()
})

-------------------------------------------------------------------------------------
    
或者还可以安装第三方模块(npm i cors)

例如:

//导入包
const cors=require('cors')
//使用
app.use(cors());
/*直接使用这个模块,便可省略在中间件中写的解决跨域问题的代码*/
JSONP(前后端配合)
■第二种:JSONP(前后端配合)
曾经的跨域杀手,专治各种跨域问题。现在慢慢的淡出历史舞台
PS:面试官特别喜欢问这个,因为这个有一定的技术难度,也能体现一个人的实际开发经验
jsonp是前后端来配合使用的.
使用原理:通过动态创建script标签通过script标签的src请求没有跨域限制来获取资源


补充知识:
浏览器页面上使用ajax发请求,当前页面地址和ajax请求的地址不同源,才会有跨域限制
但script、img、link标签中的src属性发的请求都没有跨域限制


使用jsonp原理:
这样便可以用script标签中的src来操作,去访问后端地址的接口时,前后端规定好使用的get请求传入的参数名便可,这样也没有了跨域限制


-----------------------------------------------------------------------------------------
前端页面,例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSONP</title>
</head>
<body>
    <script>
        function print(obj){
            alert(obj.user)
            alert(obj.data)
        }
    </script>
    <!-- 前端页面:访问后端API,传入后端指定get参数,后端处理返回后,接受到返回的调用和实参对象来使用 -->
    <script src="http://127.0.0.1:8888/getAll?fun=print"></script>
</body>
</html>

-----------------------------------------------------------------------------------------
后端页面,例如:

//导包
const express=require("express")

//创建服务器
const app=express()

app.get('/getAll',(req,res)=>{
    //接受到前端传入的get参数,当作函数调用这个参数,并传入实参对象,最后返回前端
    res.send(`${req.query.fun}({"user":"我是jine","data":"成功调用√"})`)
})

//启用服务器
app.listen(8888,()=>{
    console.log("服务器成功启动√")
})



或者还可以直接在Ajax请求时,加上 dataType:'jsonp'

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>点击哟</title>
    <script src="https://jine.oss-cn-beijing.aliyuncs.com/API/jquery-3.5.0.js"></script>
    <script>
        $(()=>{
            let $btn= $('button')
            $btn.on("click",()=>{
                $.ajax({
                    url:'http://127.0.0.1:8888/getAll',
                    dataType:'jsonp',
                    success:(backData)=>{
                        alert(backData.user)
                        alert(backData.data)
                    }
                })

                // 如果访问的接口支持jsonp,那么发送ajax便可以使用jsonp
                //  ajax加 dataType:'jsonp' 便可使用
                //  加的原理是:自动创建一个script标签,用他的src属性去请求服务器

                //注意:后端中的参数必须是callback,因为使用ajax开启jsonp,src传递的参数是callback,所以要一致
            })
        })
    </script>
</head>
<body>
    <button>点击我哟~</button>
</body>
</html>

"注意:后端中的参数必须是callback,因为使用ajax开启jsonp,src传递的参数是callback,所以要一致"
或者用jQuery中的$.getJSON()方法允许通过使用JSONP形式的回调函数来加载其他网域的JSON数据

$.getJSON('http://127.0.0.1:8080?callback=?',(data)=>{
    console.log(data)
})

"注意:$.getJSON()方法的一个参数表示url,需要在该参数后面添加 callback=? 。jQuery将? 自动替换为正确的函数名,以执行回调函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值