前端程序员必须要知道的跨域问题以及解决方法

简介: 前端程序员必须要知道的跨域问题以及解决方法

大厂面试题分享 面试题库

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

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

前言

前端程序员必须要知道的跨域问题以及解决方法

node 代理

原理

同源策略发生在浏览器不发生在服务端,通过一个可以跨域的node代码,帮前端请求其他后端的数据(即自己写一个后端向其他后端发请求)。图解如下图:

代码实现

两台机器连接在同一个局域网,自己的前端:

   var ajax = new XMLHttpRequest()
            ajax.open('get', 'http://localhost:3001')
            ajax.send()
            ajax.onreadystatechange = () => {
                if (ajax.readyState == 4 && ajax.status == 200) {
                    console.log(ajax.responseText);
                }
            }

自己的后端:

const http = require('http');
// const urllib = require('url');
http.createServer(function (req, res) {
    res.writeHead(200, {
        "Access-Control-Allow-Origin": 'http://127.0.0.1:5500',//只允许自己前端请求
    })
    http.request({
        host: '别人的ip地址',
        port: '别人后端运行的端口号',
        method: 'GET',
    }, result => {
        result.on('data', function (msg) {
            console.log(msg.toString());
            //拿到数据返回给自己的前端
            res.end(msg.toString())
        })
    }).end()
    // res.end(JSON.stringify({ msg: 'hello world' }))
}).listen(3001, () => {
    console.log('listening on port 3001');
});

Nginx

原理

它的实现原理和 node 代理是一样的,只不过 node 代理是通过自己写的后端向别人的后端发请求,而 Nginx 是一款软件,使用时只需要配置文件。

简介

Nginx 是开源的轻量级 Web 服务器、反向代理服务器,以及负载均衡器和 HTTP 缓存器。其特点是高并发,高性能和低内存。它专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率。

Nginx配置文件

Nginx 配置文件由三部分组成:

...              //全局块
events {         //events块
   ...
}
http      //http块
{
    ...   //http全局块
    server        //server块
    { 
        ...       //server全局块
        location [PATTERN]   //location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     //http全局块
}

第一部分 全局块

主要设置一些影响 Nginx 服务器整体运行的配置指令。 比如: worker_processes 1; worker_processes 值越大,可以支持的并发处理量就越多。

第二部分 events

events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接。 比如: worker_connections 1024; 支持的最大连接数。

第三部分 http

http 块又包括 http 全局块和 server 块,是服务器配置中最频繁的部分,包括配置代理、缓存、日志定义等绝大多数功能。

server块:配置虚拟主机的相关参数。

location块:配置请求路由,以及各种页面的处理情况。

使用 NGINX 作为 Node.js 代理

创建代理服务器块:在配置文件中,你需要创建一个新的服务器块来定义Node.js代理。 看下面代码:

server {
    listen 80;
    server_name your-domain.com;
    location / {
        proxy_pass http://localhost:3000;  //将代理请求转发至Node.js应用的地址和端口
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

在上述示例代码中,your-domain.com应替换为你的域名或服务器IP地址。proxy_pass指令用于将请求转发到Node.js应用的地址和端口。这里假设Node.js应用正在本地的 3000 端口上运行,你需要根据实际情况进行修改。

以上这两种还有上篇文章讲到的两种共四种才是我们最常见的也是应用范围最广的处理跨域的方法,那接下来我们要聊的是不常见的在某些情况下才用得到的方法。

postMessage

有一个比较老的标签<iframe></iframe>可以用于页面嵌套子页面,postMessage方法是window上的方法,可以用在此;当页面中使用了iframe嵌套了子页面,父子页面不同源时,postMessage可以实现通信。

直接看代码:

<!-- 父页面 -->
<body>
    <h1>这是首页</h1>
    <iframe id="another" src="http://127.0.0.1:63251" frameborder="4" width="500" height="400"></iframe>
    <script>
        document.getElementById('another').onload = function () {
            // console.log(this.contentWindow);
            this.contentWindow.postMessage({ name: 'song', age: 18 }, 'http://127.0.0.1:63251')
            window.onmessage = function (e) {
                console.log(e.data);
            }
        }
    </script>
</body>
<!-- 子页面 -->
<body>
    <h3>another page</h3>
    <script>
        window.onmessage = function (e) {
            console.log(e.data, '-----');
            e.source.postMessage(`${e.data.name}今年${e.data.age}`, e.origin)
        }
    </script>
</body>

domain

这个方法和postMessage方法一样,也是用在<iframe></iframe>标签上解决跨域的;只需要声明父子页面的document.domain='xxx',来告诉浏览器无需跨域。

代码如下:

<!-- 父页面 -->
<body>
    <h1>这是home 页面</h1>
    <iframe id="about" src="http://127.0.0.1:50250/" frameborder="1"></iframe>
    <script>
        document.domain = '127.0.0.1'//告诉浏览器域名一样,只要域名一样就能通信
        document.getElementById('about').onload = function () {
            console.log(this.contentWindow.data);//获取到子页面的数据
        }
    </script>
</body>
<!-- 子页面 -->
<body>
    <h3>about page</h3>
    <script>
        document.domain = '127.0.0.1'
        var data = '这是about页面的数据'
    </script>
</body>

WebSocket

是什么?

WebSocket是一种在Web应用程序中实现全双工通信的协议。它允许服务器和客户端之间建立持久的连接,实现实时数据传输和即时通信。Socket协议不受同源策略的影响,可以跨域。

一般工作流程

  1. 握手(Handshaking):在建立WebSocket连接之前,客户端和服务器之间进行一次初始的HTTP握手。客户端发送一个包含特定头部信息的HTTP请求给服务器,服务器验证这个请求,并在响应中返回特定的头部信息,表示握手成功。
  2. 连接建立:一旦握手成功,WebSocket连接就建立起来了,服务器和客户端之间可以进行实时的双向通信。
  3. 数据传输:在WebSocket连接建立后,服务器和客户端可以通过发送消息进行实时的双向通信。服务器和客户端可以随时发送消息给对方,而不需要通过传统的HTTP请求-响应模式。
  4. 连接关闭:当通信结束或需要关闭连接时,服务器或客户端可以发送一个特定的关闭帧,表示关闭WebSocket连接。

代码演示

前端:

<body>
    <script>
        function myWebScoket(url, params) {
            return new Promise(function (resolve, reject) {
                const scoket = new WebSocket(url) // 对这个url建立scoket连接
                scoket.onopen = () => { // 向后端发送数据
                    scoket.send(JSON.stringify(params))
                }
                // 接受响应
                scoket.onmessage = (res) => {
                    resolve(res.data)
                }
            })
        }
        myWebScoket('ws://localhost:3000', { name: 'song', age: 20 })
            .then(data => {
                console.log(data);
            })
    </script>
</body>

后端:

const WebSocket = require('ws');
const ws = new WebSocket.Server({ port: 3000 })
ws.on('connection', (obj) => { // 前端跟我建立了连接
    obj.on('message', (msg) => { // 前端给我传递了数据
        console.log(msg.toString());
        const data = JSON.parse(msg.toString());
        let age = data.age
        setInterval(() => {
            console.log(age);
            obj.send(`${data.name} 今年 ${age++} 岁了`);
        }, 2000)//每隔两秒打印一次
    })
})

小结

对于跨域问题以及解决办法,这两篇文章我们详细地描述了一番,大概就是这7种解决跨域的手段。文章可能有遗漏或错误,欢迎各位大佬指出。

 

大厂面试题分享 面试题库

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

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

相关文章
|
7月前
|
前端开发 JavaScript 应用服务中间件
前端跨域问题解决Access to XMLHttpRequest at xxx from has been blocked by CORS policy
跨域问题是前端开发中常见且棘手的问题,但通过理解CORS的工作原理并应用合适的解决方案,如服务器设置CORS头、使用JSONP、代理服务器、Nginx配置和浏览器插件,可以有效地解决这些问题。选择合适的方法可以确保应用的安全性和稳定性,并提升用户体验。
4723 90
|
7月前
|
人工智能 前端开发 JavaScript
AI程序员:通义灵码 2.0应用VScode前端开发深度体验
AI程序员:通义灵码 2.0应用VScode前端开发深度体验,在软件开发领域,人工智能技术的融入正深刻改变着程序员的工作方式。通义灵码 2.0 作为一款先进的 AI 编程助手,与广受欢迎的代码编辑器 Visual Studio Code(VScode)相结合,为前端开发带来了全新的可能性。本文将详细分享通义灵码 2.0 在 VScode 前端开发环境中的深度使用体验。
1202 2
AI程序员:通义灵码 2.0应用VScode前端开发深度体验
|
7月前
|
前端开发 JavaScript 安全
剖析跨域问题始末及其解决方案——前端必备交叉知识(一)
跨域问题是前端开发中的常见挑战,了解并掌握不同的跨域解决方案能帮助你更高效地进行开发工作。本文对同源策略、跨域以及解决跨域的三种方案: CORS、JSONP、代理等跨域技术进行了介绍。选择合适的跨域解决方案非常重要。 在实际开发中,推荐优先考虑使用 CORS,因为它是现代浏览器支持的标准,且安全性较高。如果服务器无法修改,则可以考虑使用代理。如果是特殊情况,可以使用 JSONP,但要注意安全性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错
|
9月前
|
前端开发 JavaScript Java
前端解决axios请求的跨域问题【2步完成】
本文介绍如何通过前端配置解决跨域问题,主要针对Vue项目中的`vite.config.js`文件进行修改。作者在联调过程中遇到跨域报错
441 1
|
存储 JavaScript 前端开发
后端程序员的前端基础-前端三剑客之JavaScript
后端程序员的前端基础-前端三剑客之JavaScript
257 121
|
11月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
175 3
springboot解决js前端跨域问题,javascript跨域问题解决
|
11月前
|
前端开发 JavaScript 安全
揭秘!前端大牛们如何高效解决跨域问题,提升开发效率!
【10月更文挑战第30天】在Web开发中,跨域问题是一大挑战。本文介绍前端大牛们常用的跨域解决方案,包括JSONP、CORS、postMessage和Nginx/Node.js代理,对比它们的优缺点,帮助初学者提升开发效率。
341 4
|
运维 前端开发
前端使用antdesign导出插件跨域问题
前端使用antdesign导出插件跨域问题
182 5
|
前端开发 JavaScript API
前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法
前端基于XLSX实现数据导出到Excel表格,以及提示“文件已经被损坏,无法打开”的解决方法
1043 0
|
JavaScript 前端开发 程序员
后端程序员的前端必备-jQuery核心学习笔记
后端程序员的前端必备-jQuery核心学习笔记
137 13

热门文章

最新文章

  • 1
    前端工程化演进之路:从手工作坊到AI驱动的智能化开发
  • 2
    Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
  • 3
    实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数