(十四)跨域的理解以及问题解决

一、跨域

  • 跨域是由于浏览器的同源策略,当浏览器中一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
  • 同源策略(SOP)是一种约定,同源是指 协议、域名、端口号
    三者相同,即便两个不用的域名指向同一个ip地址,也非同源。同源策略可以防止浏览器收到XSS、CSFR等攻击。
  • 用户在使用浏览器的情况下会使用到 CORS,因为控制访问权限的是浏览器而非服务器。因此使用其它客户端的时候无需关心任何跨域问题。

二、如何解决跨域问题

1、代理配置

①webpack代理配置,Vue脚手架创建的项目在vue.config.js文件配置以下代理

devServer:{
        proxy:{
            '/api': {
                // 需代理地址
                target: 'https://example.com/',
                host: '0.0.0.0',
			    port: port,
			    // https: true, // 允许https接口代理
			    // hotOnly: true, // 热更新
			    // 如果是代理到域名,需要设置changeOrigin: true
                changeOrigin: true
                // 路径重写(代理重写)
                // 如果实际接口没有当前path则需重写路径,且使用调用接口的时候需要加上当前path
                // 比如访问的API路径:/api/singIn,设置pathRewrite: {’^/api’ : ‘’},后,最终代理访问的路径:https://example.com/singIn
                pathRewrite:{
                    '^/api':''
                }
            },
        },
    }

②nginx代理配置在nginx.conf文件内配置

location /api {
     rewrite  ^/api/?(.*)$ /$1 break;
     
     # proxy_set_header Host $host;
     # proxy_set_header X-Real-IP $remote_addr;
     # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     
     # 允许cros跨域访问
     # add_header 'Access-Control-Allow-Origin' '*';
     
     proxy_pass http://0.0.0.0:8080/; # 转发地址
}

2、JSONP

  • 利用script标签 src属性,不存在跨域限制。发送 GET 请求 (无法实现POST请求)
  • src = “http://127.0.0.1:4000/list?callback=func”
    向服务器发送请求,同时会把本地的一个函数传递给服务器。
  • JSONP需要服务器端支持。
  • 核心思想:网页通过添加< script >标签,向服务器请求 JSON
    数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
  • JSONP是解决跨域的方法之一,它与AJAX并无任何关联。
  • JSONP向服务端发送的请求,type的类型为scrpt,这与JSONP的核心思想相对应。
  • AJAX向服务端发送的请求,它的type类型为一个xhr对象,AJAX的源码就是先创建一个xhr的对象,然后发送请求,所以JSONP与AJAX没有任何关系,只是AJAX封装了JSONP。
    在这里插入图片描述

在这里插入图片描述
①原生js使用JSONP

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function getData(data){
            document.write(JSON.stringify(data))
        }
    </script>
    <script src="http://localhost:3000/jsonp/jsonp?callback=getData"></script>
</body>
</html>

②jQuery 使用 JSONP

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JSONP 实例</title>
    <script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body>
    <div id="divCustomers"></div>
    <script>
        // 直接只用$.getJSON调用
        $.getJSON("http://localhost:3000/jsonp/jsonp?callback=?", function (data) {
            document.write(JSON.stringify(data))
        });
        // or
        // 使用ajax,dataType设置为jsonp调用
        $.ajax({
            type : "GET",
            dataType : "jsonp",
            url : "http://localhost:3000/jsonp/jsonp",
            success : function(data){
                document.write(JSON.stringify(data))
                console.log('data', data)
            }
        })
    </script>
</body>
</html>

JSONP的缺点:1.不安全;2.只支持get 请求;3.需要服务器支持

3、CORS

CORS(Cross-Origin Resource Sharing,跨域资源共享),允许浏览器向跨域服务器,发出XMLHttpRequest请求,从而克服了AJAX只能使用限制。
XMLHttpRequest:Ajax的核心对象
CORS需要浏览器和服务器同时支持。

预检请求
跨域请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

如果服务器允许跨域,需要在返回的响应头中携带下面信息:

'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': '*', // 允许访问的域(协议+域名+端口)
'Access-Control-Allow-Methods': "POST,GET,DELETE,PUT,OPTIONS" // 允许请求方式用着五种`
'Access-Control-Allow-Headers'""允许携带的头
'Access-Control-Max-Age'""本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了

缺点:要不让所有源都可以(所有源都不能携带cookie)要不然就只能允许一个源,可以携带cookie

参考:
1、https://blog.csdn.net/weiCong_Ling/article/details/130624934
2、https://blog.csdn.net/qq_46548855/article/details/129268826

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值