跨域的五种最常见解决方案

简介: 跨域的五种最常见解决方案

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

什么是跨域

跨域不是问题,是一种安全机制。浏览器有一种策略名为同源策略,同源策略规定了部分请求不能被浏览器所接受。

值得一提的是:同源策略导致的跨域是浏览器单方面拒绝响应数据,服务器端是处理完毕并做出了响应的。

什么是同源策略

一个url由三部分组成:协议,域名(ip地址),端口

只有当协议,域名,端口都一致的时候,才被称为同源。

而同源策略规定,只有发送请求的那一边和接受请求的那一边处于同源的情况下,浏览器才会接受响应。

举个例子

发送请求地址:http:47.96.127.5:8080/index    接受请求地址:http:47.96.127.5:8081/index //不同源 端口不同
发送请求地址:http:47.96.127.5:8080/index     接受请求地址:http:47.96.127.6:8080/index //不同源 ip不同
发送请求地址:http:47.96.127.5:8080/index     接受请求地址:https:47.96.127.5:8080/index //不同源 协议不同
发送请求地址:http:47.96.127.5:8080/index     接受请求地址:http:47.96.127.5:8080/login //同源 协议,端口,ip都相同,路径不同无所谓

而当我们的请求不符合同源策略的时候。往往会出现以下错误👇

解决跨域常见的5种方法

第一种:JQuery的ajax(推荐JQuery项目中使用)

jq的ajax自带解决跨域的方法。底层原理采用的JSONP的跨域解决方案。如下

function callback(){
    console.log("月薪一千五,心比美式苦")
}
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp  设置跨域的重点
    jsonpCallback: "callBack",  // 回调函数
});

在JQ项目中,这是最常见的解决方案。

第二种:script标签解决跨域(远古Web项目中使用)

如果你的项目是祖传下来的。没有框架连JQuery都没有。没关系,我们可以尝试使用原生的方法去解决。

原生采用的是script标签可以不受跨域限制的特性来实现跨域。

  <script>
            // 回调
            function callBack(res) {
                console.log("跨域的回调",res);
               // ...完成你所有操作后记得删除script↓
               document.head.getElementsByClassName("script")[0].remove();
            }
            const scriptDom = document.createElement('script');
            scriptDom.type = 'text/javascript';
            scriptDom.class = 'script'; //用于删除
            // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
            scriptDom.src = 'http://192.167.0.152:9996/inface?callback=callBack';
            document.head.appendChild(script); //将标签挂载到dom上
        </script>

这里需要注意的是,使用完请求之后记得删除script,否则会随着请求的变多script标签会一直挂载在DOM上。

在远古的web中,这是一种方案。但现在已经不用了。

vue/react/jq等框架性项目中不要使用这种方法,不是不行,只是有更好的选择

第三种:前端代理解决跨域

每一个框架的代理配置都不太一样。这里仅以我使用的umi.js(react)为例。

Umi.js框架会有 config.ts / config.js 文件,文件中会有proxy字段、字段按图中配置方法。即可完成跨域

第四种:服务端代理(Nginx代理)

nginx代理一般使用在生产环境。是服务端解决跨域的一种方案。

简单配置模板👇

#如果监听到请求接口地址是 www.xxx.com/api/page ,nginx就向http://www.yyy.com:9999/api/page这个地址发送请求
server {
     listen       80; 
        server_name  www.xxx.com;
        #判过滤出含有api的请求
        location /api/ { 
            proxy_pass http://www.yyy.com:9999; #真实服务器的地址
        }
}

注意,nginx配置完代理后需要重启nginx,nginx代理是生产环境的常用方案

第五种:后台(逻辑层)添加响应头解决

Access-Control-Allow-Origin响应头的意思是,安全同行的请求。

举个例子 http://192.168.0.103:8080http://192.168.0.102:8080 发送了请求,结果因为域名不一样,在返回信息的时候因为IP地址不一致被拦截。

但是如果http://192.168.0.102:8080 在响应头中的 Access-Control-Allow-Origin 字段中携带上属性值'http://192.168.0.103:8080' 如下

//响应头
Access-Control-Allow-Origin':'http:/ /192.168.0.103:8080'

这就等于告诉浏览器,http://192.168.0.102:8080 这个地址是安全的,请不要拦截。

这样,http://192.168.0.103:8080 就可以接受来自 http://192.168.0.102:8080 返回的信息。

当然,我们也可以进行所有域名均不拦截的设置(如下)

//响应头
// * 代表所有域名均不拦截
Access-Control-Allow-Origin':'*'

node案例如下

res.writeHead(200, {
    Access-Control-Allow-Origin':'http://192.168.0.103:8080'
});
//或者
res.writeHead(200, {
    Access-Control-Allow-Origin':'*'
});

并不建议此种方案,因为安全性不高。自己写小练习的时候建议使用,因为真的很方便。

总结

跨域的常见的五种解决方案如下

  1. jsonp,代表:jquery的$.ajax。(仅限JQuery项目使用)
  2. script标签解决跨域(远古web使用的方案,已不建议使用)
  3. 前端代理
  4. nginx代理
  5. 设置响应头(不建议使用,安全性不高,小练习可以用用,方便)

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
7月前
|
IDE JavaScript 前端开发
【Web3新手教程】如何获取 stargate 跨链数据
在本教程中,我们将深入探讨Stargate Finance的世界,探索其复杂的功能、特性以及通过 Chainbase 提供的宝贵数据集。特别是这个DeFi数据集使我们能够无缝地获取交易数据。
63 0
|
8月前
|
Linux 网络安全 Apache
在树莓派上搭建web站点并发布互联网上线【无需公网IP】
在树莓派上搭建web站点并发布互联网上线【无需公网IP】
|
9月前
|
存储 缓存 运维
【运维知识进阶篇】集群架构-HTTP协议详解
【运维知识进阶篇】集群架构-HTTP协议详解
50 0
|
9月前
|
弹性计算 运维 负载均衡
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)(一)
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)
264 0
|
9月前
|
运维 负载均衡 PHP
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)(四)
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)(四)
247 0
|
9月前
|
域名解析 运维 负载均衡
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)(二)
【运维知识进阶篇】用阿里云部署kod可道云网盘项目(HTTPS证书+负载均衡+两台web)(二)
271 0
|
10月前
|
存储 弹性计算 安全
HTTP、CDN 和 OSS 为什么过时了?深入聊聊 Web3 世界中的协议和硬盘:IPFS
HTTP、CDN 和 OSS 为什么过时了?深入聊聊 Web3 世界中的协议和硬盘:IPFS
230 0
|
11月前
|
缓存 JSON 前端开发
✨✨✨ ServiceWorker 让你的网页拥抱服务端的能力
ServiceWorker 是一个运行在浏览器背后的独立线程,它拥有访问网络的能力,可以用来实现缓存、消息推送、后台自动更新等功能,甚至可以用来实现一个完整的 Web 服务器。
155 0
✨✨✨ ServiceWorker 让你的网页拥抱服务端的能力
|
数据采集 机器学习/深度学习 安全
阿里云Web应用防火墙在护航场景下的技术优势?
阿里云Web应用防火墙在护航场景下的技术优势?
164 0
|
安全