当前位置: 首页 > news >正文

色块网站中国政务服务网

色块网站,中国政务服务网,网络设计是本科,什么网站做兼职最好跨域是开发中经常会遇到的一个场景,也是面试中经常会讨论的一个问题。掌握常见的跨域解决方案及其背后的原理,不仅可以提高我们的开发效率,还能在面试中表现的更加游刃有余。 因此今天就来和大家从前端的角度来聊聊解决跨域常见的几种方式。…

跨域是开发中经常会遇到的一个场景,也是面试中经常会讨论的一个问题。掌握常见的跨域解决方案及其背后的原理,不仅可以提高我们的开发效率,还能在面试中表现的更加游刃有余。


因此今天就来和大家从前端的角度来聊聊解决跨域常见的几种方式。

什么是跨域

在讲跨域之前,我们先来看看URL的组成内容:


一个URL的组成,通常包含协议、主机名、端口号、路径、查询参数和锚点几个部分。


这里展示了一个URL的示例:

https://www.example.com:8080/path/resource.html?page=1&sort=desc#header

在上述示例中:
● 协议为HTTPS
● 主机名为www.example.com
● 端口号为8080
● 路径为/path/resource.html
● 查询参数为page=1&sort=desc
● 锚点为header


所谓跨域,指的是请求URL中协议、主机名、端口号中任意一个部分不相同。


以上述URL为例,下面几种写法都算是和它跨域:

ttp://www.example.com:8080/    // 协议不同
https://www.example.a.com:8080/ // 主机名不同
https://www.example.com:8081/   // 端口号不同

为什么会跨域

其实跨域问题的出现是受限于浏览器的同源策略

所谓同源策略,其实是浏览器的一种安全机制,用于限制一个网页中的网络请求仅能够访问来自同一源(域名、协议和端口号均相同)的资源,主要目的是防止恶意网站通过脚本窃取其他网站的敏感数据,保障用户的隐私和安全。

当浏览器端的脚本(js文件)访问了其他域的网络资源时,就会出现跨域问题。

如何解决跨域

前文说到,跨域问题的出现是受限于浏览器的同源策略,那么常见的解决跨域问题的方案,其实也是围绕着浏览器展开的:

1.代理服务器

在我们平常的开发中,解决跨域问题最常使用的方案是使用代理服务器

代理服务器解决跨域问题其实是抓住了同源策略只受限于浏览器访问服务器,对于服务器访问服务器并没有限制的特点,作为中间服务器做了一个请求转发的功能

具体来说,就是前端工程师编写的网页运行在由webpack等脚手架搭建的代理服务器上,当前端网页在浏览器中发起网络请求时,其实这个请求是发送到代理服务器上的,然后代理服务器会将请求转发给目标服务器,再将目标服务器返回的响应转发给客户端。

代理服务器在此过程中扮演了一个中转的角色,可以对请求和响应进行一些修改、过滤和拦截,以实现一些特定的功能。因为前端网页运行在代理服务器上,所以不存在跨域问题。

那么在线上环境和开发环境下,代理服务器是如何做请求转发的呢?

1.线上环境

在线上环境下,我们一般会采用nginx来做反向代理,从而把前端的请求转发到目标接口上。

nginx是一个轻量级高并发的web服务器,基于事件驱动,而且跨平台,window和Linux都可以进行配置。

它作为代理服务器来解决开发中的跨域问题的主要方法就是监听线上前端网址的运行端口,然后碰到包含特殊标记的请求后就进行请求转发

2.开发环境

在开发环境下,无论是借助于webpack还是使用vite或其他脚手架搭建的前端项目,解决跨域问题的核心是借助http-proxy-middleware中间件实现的。而http-proxy-middleware中间件的核心又是对http-proxy的进一步封装。

这里先展示一下在项目中使用http-proxy-middleware来实现请求转发功能的示例代码:

const { createProxyMiddleware } = require('http-proxy-middleware');module.exports = {server: {proxy: {// 将 /api/* 的请求代理到 http://localhost:3000/*'/api': {target: 'http://localhost:3000',changeOrigin: true,pathRewrite: { '^/api': '/' }}}}
};

接着我们可以自己使用原生node,借助http-proxy库来搭建一个具有请求转发功能的代理服务器Demo,感兴趣的朋友可以自己测试玩玩

1. 首先需要创建一个空文件夹(全英命名)作为项目文件夹,然后使用npm init -y命令将项目升级为node的项目:

npm init -y

2. 接着在项目根目录下创建一个index.html文件用于发起跨域请求:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>请求转发测试</title>
</head><body><h1>请求转发测试</h1><p id="message"></p><script>fetch('/api/login').then(response => response.text()).then(data => {document.getElementById('message').textContent = data;});</script>
</body></html>

3. 接着在项目根目录下新建index.js文件来编写服务端的代码。
index.js文件是实现具有请求转发功能的代理服务器的核心文件。

const http = require('http');
const httpProxy = require('http-proxy');
const fs = require('fs');
const path = require('path');// 创建代理服务器实例
const proxy = httpProxy.createProxyServer({});// 创建HTTP服务器
const server = http.createServer((req, res) => {if (req.url === '/' || req.url.endsWith('.html')) {// 读取HTML文件const filename = path.join(__dirname, 'index.html');fs.readFile(filename, 'utf8', (err, data) => {if (err) {res.writeHead(500);res.end('Error reading HTML file');} else {res.writeHead(200, { 'Content-Type': 'text/html' });res.end(data);}});} else if (req.url.startsWith('/api')) {// 重写路径,替换跨域关键词req.url = req.url.replace(/^\/api/, '');// 将请求转发至目标服务器proxy.web(req, res, {target: 'http://localhost:3000/',changeOrigin: true,});    }
});// 监听端口
server.listen(8080, () => {console.log('Server started on port 8080');
});

4. 接着编写目标服务器target.js文件的内容,用于测试跨域访问:

const http = require('http');const server = http.createServer((req, res) => {if (req.url.startsWith('/login')) {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('我是localhost主机3000端口下的方法,恭喜你访问成功!');} else {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('Hello, world!');}
});server.listen(3000, () => {console.log('Target server is listening on port:3000');
})

5. 打开终端,输入启动目标服务器的命令:

node ./target.js //项目根目录下执行

6. 再开一个终端启动代理服务器,等待浏览器端发起请求就可以啦:

node ./index.js //项目根目录下执行

7. 最后在浏览器里访问http://localhost:8080, 打开控制台即可查看效果:

可以发现,浏览器network模块的网络请求确实是访问的8080端口的方法,但是我们的服务器默默的做了请求转发的功能,并将请求转发获取到的内容返回到了前端页面上。

其实http-proxy是对node内置库http的进一步封装,网络请求的核心部分还是使用http创建一个服务器对象去访问的。感兴趣的同学可以再读读http-proxy的源码~

除了代理服务器这种绕过浏览器同源策略的解决方式外,从前端的角度解决跨域问题还有如下一些常见的方法:

1.借助JSONP

JSONP的原理是通过动态创建<script>标签,向服务器发送请求并在请求URL中传递一个回调函数名(通常是在本地定义的函数名),服务器在返回的数据中将这个回调函数名和实际数据一起封装成一个JavaScript函数的调用,返回给客户端,客户端利用该回调函数对数据进行处理。

JSONP之所以能够跨域请求数据,是因为浏览器对于<script>标签的请求不会受到同源策略的限制。

需要注意的是,使用JSONP技术的前提是服务器需要支持JSONP的方式,即在返回的数据中包含回调函数名和实际数据的封装,否则客户端无法处理返回的数据。

此外,JSONP只支持GET请求,不支持POST等其他HTTP请求方式,因为<script>标签只支持GET请求。

因此JSONP这种方式在我们的开发中使用的场景不多。

2.使用CORS

CORS全称为Cross-Origin Resource Sharing,它通过HTTP头部信息告诉浏览器哪些跨域请求是被允许的,从而实现安全的跨域访问。

CORS解决跨域需要浏览器端和服务器端的配合。原理是在服务器端设置HTTP头部信息,告诉浏览器允许哪些源(域名、协议、端口)访问服务器上的资源,如果请求的源不在允许的列表中,则浏览器将拒绝访


问。

服务器可以通过设置Access-Control-Allow-OriginAccess-Control-Allow-HeadersAccess-Control-Allow-Methods等HTTP头部信息来控制跨域访问权限。

具体地,当浏览器发起跨域请求时,会先发送一个OPTIONS请求(预检请求),询问服务器是否允许该跨域请求。

服务器接收到该请求后,根据请求中的HTTP头部信息判断是否允许该请求。

如果允许,则返回相应的HTTP头部信息告知浏览器可以继续发送真正的跨域请求。如果不允许,则返回一个错误状态码,告诉浏览器该请求被拒绝。

预检请求时,请求头常见参数有

请求头
Origin表示请求的源地址,即发起跨域请求的域名
Access-Control-Request-Method表示实际请求采用的HTTP方法
Access-Control-Request-Headers表示实际请求中所携带的额外请求头信息,比如自定义请求头等

预检请求时,响应头常见参数有

响应头
Access-Control-Allow-Origin*、origin…
Access-Control-Allow-HeadersPOST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-MethodsContent-Type, Authorization…
Access-Control-Allow-Credentialstrue
Access-Control-Max-Age86400

需要注意的是,使用CORS的前提是服务器需要设置相关的HTTP头部信息,且浏览器支持CORS。此外,CORS只支持现代浏览器,对于一些老旧的浏览器可能不支持CORS。

3.其他方案

比如WebSocketpostMessage等等


总结

近年来,随着前后端技术的飞速发展,前后端独立开发逐渐成为主流的开发模式。前后端程序员只需约定好接口,然后独自进行相应模块的开发,最后进行接口联调即可。在接口联调过程中,开发环境下的跨域就是一个需要解决的问题。


除此之外,当前后端项目打包上云后,前端页面通过线上地址访问后台接口时,线上环境下的跨域也是一个需要解决的问题。


本文讲述了几种常见的跨域解决方案,这些方案各有优缺点,大家可以根据实际情况选择适合的方案来解决对应的跨域问题~

http://www.yayakq.cn/news/270835/

相关文章:

  • 黔江网站制作个人做当地旅游网站
  • 广告公司广告牌制作徐州优化网站建设
  • 网站新闻被百度收录北京市建设工程信息网官方网站
  • 单纯做网站的公司wordpress怎么创建自己的博客
  • 自动提卡的网站怎么做的南昌seo推广公司
  • 如何查外贸网站外链防疫大数据平台
  • oa报表网站开发wordpress百万数据
  • 凡科做网站类型应该做哪个怎么开发软件app软件
  • 网站开发所需费用支出有哪些网站后期维护收费
  • 网站页面制作多少钱如何优化网站快速排名
  • 寻找网站设计与制作免费进入正能量的网站
  • 重庆市建设厅官方网站上海造价信息网
  • 江苏建设教育网站苏宁易购
  • 有哪些炫酷的官方网站怎样维护公司网站
  • 网站群建设 中标耐克官网网站设计
  • 最好的科技网站建设wordpress占用内存过大
  • 十堰网站推广张家港企业网站设计
  • 公司网页网站建设ppt模板网站开发融资
  • 昆山市网站建设深圳市中心在哪个位置
  • 404做的好的网站网站设计建设专业服务
  • 工业信息化部网站备案福州网
  • 美丽说网站优化西安官网seo推广
  • 电子商务网站成功的关键是如何高效的完成网站建设步骤
  • 汕头整站优化wordpress更换语言
  • 小型网站如何做做跳转链接到自己的网站
  • 门户网站建设工作流程中山网页模板建站
  • 织梦网站文章发布模板下载500个企点qq大概多少钱
  • 做视频网站可以自学吗做网站流量优化都是什么
  • 5年网站续费多少钱码制作二维码官网
  • 天河建网站的公司企业网站 asp.net