跨域问题及解决方案

一、首先要了解什么是什么域?其次什么跨域?进而什么是跨域问题?

1、什么是域:

域是一个站点的统称,称之为域名,一个网站,叫一个网域,分为域内域外,出了这个站就是其他区域,网站通过域名实现区分隔离,底层通过IP 实现资源占有和分布。

2、什么是跨域:

跨域就是不同站点之间的资源访问获取,调用就是跨域,跨域行为至少跳跃两个站点。

3、什么是跨域问题:

由于跨域产生不同网站访问资源和信息的友好程度不同,被人为的分为了可信域和不可信域,所以当我们跨域的时候总是在可信域内活动,而不是在不可信仰域内活动。由此产生的信誉问题引发的跨域安全型问题,以及调用和被调用源的根本可行度问题。跨域也是实现资源分配的一种解决办法。

二、跨域的根本原因:

是站点之间的权限和资源受控被隔离导致的访问限制问题。
1.跨域解决方案一:cors技术
CORS :全称cross origin resource share (资源共享)

工作原理: 服务器 在返回响应报文的时候,在响应头中 设置一个允许的header

res.setHeader(‘Access-Control-Allow-Origin’, ‘*’)

CORS :全称cross origin resource share (资源共享)

服务器 在返回响应报文的时候,在响应头中 设置一个允许的header

三、实现跨域的解决方案

解决这个问题可以有两个方向,一个前端、一个后端

1、前端解决方案:

首先想实现跨域先弄懂什么是跨域

所谓的跨域是建立在浏览器同源策越下对异源资源进行请求的行为,

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。

它能帮助阻隔恶意文档,减少可能被攻击的媒介。目前抛开只能跨域get请求的jsonp之外流行的两种跨域方式分别是
1 cors

CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。

也就是服务器运行进行跨域请求,因为要在服务端加上cors标识一般用于服务端进行跨域操作

2 代理
因为脚本不能请求异源资源,那么将脚本和资源服务器处于同一源即可。

cors相关方法
同源安全策略 默认阻止“跨域”获取资源。但是 CORS 给了web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。

所以既然是服务器选择开发资源即可访问。所以根本原理便是在服务器的response上 加上表示可以访问资源的标识即可。

1 框架插件配置法
比如各大node框架一般都自带跨域插件,如egg-cors,koa-cors之类的

当然也可以自己写插件进行response拦截。

'use strict';
module.exports = () => {
return async (ctx, next) => {
// 处理OPTIONS请求
if (ctx.method === 'OPTIONS') {
ctx.body = '';
}
ctx.set('Access-Control-Allow-Origin', '');
// 设置所允许的HTTP请求方法
ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, PUT, POST, DELETE');
// 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段.
ctx.set('Access-Control-Allow-Headers', '
');
await next();
};
};

// add your middleware config here
config.middleware = [ 'httpError', 'cors' ];

2 通过第三方服务器为response添加上cors标识
以用nginx为例,用nginx代理资源服务器。然后在nginx内拦截response添加标识,再通过代理服务器去请求资源,nginx将自动为资源请求添加上cors标识

nginx.conf

server {
listen 9000;
server_name localhost;
location / {
proxy_pass http://localhost:8010; //代理的资源服务器
add_header 'Access-Control-Allow-Origin' $http_origin; // 全局变量获得当前请求origin,带cookie的请求不支持*
add_header 'Access-Control-Allow-Credentials' 'true'; // 为 true 可带上 cookie
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; // 允许请求方法
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; // 允许请求的 header,可以为 *
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; // OPTIONS 请求的有效期,在有效期内不用发出另一条预检请求
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
}
}

代理
在开发环境我们的页面资源一般都挂载在开发服务器上,所以只需要在开发服务器上配置代理即可,如
webpack-dev-server 的 proxy设置
也可以直接用
express + http-proxy-middleware
其目的都是通过页面服务器去代替脚本资源去向资源服务器发起请求,因为服务器之间没有同源策略从而达到跨域的目的。

还有一种方法就是,第三方服务配置跨域,就是将脚本服务器和资源服务器都通过第三方服务器上,通过配置同一个域名的不同标识来识别访问。这样在浏览器看来他们都是统一域名下的资源了。
以 nignx为例

server {
listen 9001;
server_name localhost;

charset koi8-r;

access_log logs/host.access.log main;

location / {
proxy_pass http://localhost:3000;
}

location ^~/apis/ {
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass http://localhost:8010;

}
}

2、后端解决方案:

3、热门参考文案:

https://blog.csdn.net/yup1212/article/details/87633272?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-87633272-blog-125240153.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-87633272-blog-125240153.pc_relevant_vip_default&utm_relevant_index=1

https://blog.csdn.net/tjcjava/article/details/76468225?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-76468225-blog-87633272.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1-76468225-blog-87633272.pc_relevant_vip_default&utm_relevant_index=1

https://blog.csdn.net/weixin_64214997/article/details/125240153

https://blog.csdn.net/qq_42880714/article/details/122955087

posted @ 2026-07-05 11:33  浅笑若风  阅读(14)  评论(0)    收藏  举报