首页 > 其他分享 >面试必考:全面解析跨域及其解决方案

面试必考:全面解析跨域及其解决方案

时间:2024-07-27 18:29:26浏览次数:10  
标签:const 跨域 res app 必考 面试 http data

跨域问题是前端开发中常见且必须掌握的知识点之一。本文将详细介绍跨域的概念、手写JSONP和CORS跨域代码及其原理,如何在Vue3项目中替换Mock数据接口为真实后端数据接口,以及总结九种常见的跨域解决方案。

一、什么是跨域?

跨域是指浏览器因同源策略的限制,无法访问不同源(协议、域名、端口任一不同)的资源。例如,前端页面运行在 http://example.com,但需要访问 http://api.example.com 的数据时,就会遇到跨域问题。

二、手写JSONP跨域代码及原理讲解

原理

JSONP(JSON with Padding)是一种非正式的数据传输格式,它通过 <script> 标签的 src 属性来实现跨域请求。因为 <script> 标签不受同源策略限制。

实现代码

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSONP Example</title>
</head>
<body>
    <h1>JSONP Cross-Origin Request</h1>
    <button onclick="fetchData()">Fetch Data</button>
    <script>
        function fetchData() {
            const script = document.createElement('script');
            script.src = 'http://localhost:3000/data?callback=handleResponse';
            document.body.appendChild(script);
        }

        function handleResponse(data) {
            console.log('Received data:', data);
        }
    </script>
</body>
</html>

 

后端代码(Node.js示例):

const express = require('express');
const app = express();
const port = 3000;

app.get('/data', (req, res) => {
    const callback = req.query.callback;
    const data = { message: 'Hello, JSONP!' };
    res.send(`${callback}(${JSON.stringify(data)})`);
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
});

 

三、手写跨域资源共享(CORS)处理跨域及原理

原理

CORS(Cross-Origin Resource Sharing)是一种机制,它使用额外的HTTP头来告诉浏览器,允许从其他域加载资源。服务器通过设置适当的HTTP响应头,来告诉浏览器哪些域可以访问资源。

实现代码

前端代码:

fetch('http://localhost:3000/data', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => response.json())
.then(data => console.log('Received data:', data))
.catch(error => console.error('Error:', error));

 

后端代码(Node.js示例):

const express = require('express');
const app = express();
const port = 3000;

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*'); // 允许所有域访问
    res.header('Access-Control-Allow-Methods', 'GET, POST'); // 允许的方法
    res.header('Access-Control-Allow-Headers', 'Content-Type'); // 允许的请求头
    next();
});

app.get('/data', (req, res) => {
    res.json({ message: 'Hello, CORS!' });
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
});

 

四、Vue3通用后台管理如何替换Mock数据接口为真实的后端数据接口

在Vue3项目中,我们可以通过修改API请求地址,将Mock数据接口替换为真实后端数据接口。

示例

假设我们有一个Vue3项目,之前使用Mock数据:

// api.js (使用Mock数据)
export const getData = () => {
    return new Promise((resolve) => {
        resolve({ data: 'Mock data' });
    });
};

 

现在,我们将其替换为真实后端接口:

// api.js (使用真实后端数据)
import axios from 'axios';

const BASE_URL = 'http://localhost:3000';

export const getData = () => {
    return axios.get(`${BASE_URL}/data`);
};

 

然后在组件中调用:

<template>
  <div>
    <button @click="fetchData">Fetch Data</button>
    <p>{{ data }}</p>
  </div>
</template>

<script>
import { getData } from './api';

export default {
  data() {
    return {
      data: ''
    };
  },
  methods: {
    fetchData() {
      getData()
        .then(response => {
          this.data = response.data.message;
        })
        .catch(error => {
          console.error('Error:', error);
        });
    }
  }
};
</script>

 

五、九种跨域方案的汇总

  1. JSONP:通过 <script> 标签实现跨域,只支持GET请求。
  2. CORS:通过设置HTTP头允许跨域请求,支持复杂请求。
  3. 服务器代理:如使用Node.js中间件(http-proxy-middleware)或Nginx代理请求,绕过浏览器的同源策略。
  4. WebSocket:WebSocket协议不受同源策略限制,可以实现跨域通信。
  5. PostMessage:通过 window.postMessage 实现不同窗口间的数据传递。
  6. 跨域资源嵌入:通过 <iframe><img><link><script> 等标签加载跨域资源。
  7. document.domain:适用于主域相同子域不同的跨域,通过设置相同的 document.domain 实现。
  8. window.name:通过改变窗口的 name 属性实现跨域数据传递。
  9. 跨域请求伪造(CORS Preflight):通过简单请求或预检请求绕过CORS限制。

1. JSONP示例

详见上文。

2. CORS示例

详见上文。

3. 服务器代理示例(Node.js中间件)

const { createProxyMiddleware } = require('http-proxy-middleware');
const express = require('express');
const app = express();

app.use('/api', createProxyMiddleware({
    target: 'http://backend-server.com',
    changeOrigin: true,
}));

app.listen(3000);

 

4. WebSocket示例

const socket = new WebSocket('ws://localhost:3000');

socket.onopen = () => {
    console.log('WebSocket connection opened');
    socket.send('Hello Server!');
};

socket.onmessage = (event) => {
    console.log('Received:', event.data);
};

 

后端代码(Node.js示例):

const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 3000 });

server.on('connection', ws => {
    ws.on('message', message => {
        console.log('Received:', message);
        ws.send('Hello Client!');
    });
});

 

5. PostMessage示例

<!-- parent.html -->
<iframe id="child" src="child.html" style="display:none;"></iframe>
<script>
    const child = document.getElementById('child').contentWindow;
    child.postMessage('Hello from parent!', 'http://child.com');

    window.addEventListener('message', (event) => {
        if (event.origin === 'http://child.com') {
            console.log('Received from child:', event.data);
        }
    });
</script>

<!-- child.html -->
<script>
    window.addEventListener('message', (event) => {
        if (event.origin === 'http://parent.com') {
            console.log('Received from parent:', event.data);
            event.source.postMessage('Hello from child!', event.origin);
        }
    });
</script>

 

6. 跨域资源嵌入示例

<!-- index.html -->
<script src="http://cross-origin.com/script.js"></script>

 

7. document.domain示例

<!-- parent.example.com -->
<script>
    document.domain = 'example.com';
    // 访问子域内容
</script>

 

8. window.name示例

<!-- page1.html -->
<script>
    window.name = 'data from page1';
    location.href = 'http://cross-origin.com/page2.html';
</script>

<!-- page2.html -->
<script>
    console.log(window.name); // 'data from page1'
</script>

 

9. 跨域请求伪造(CORS Preflight)示例

后端代码:

const express = require('express');
const app = express();

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    if (req.method === 'OPTIONS') {
        return res.sendStatus(204); // 对预检请求直接返回204状态码
    }
    next();
});

app.post('/api', (req, res) => {
    res.json({ message: 'Data received' });
});

app.listen(3000, () => {
    console.log('Server running at http://localhost:3000');
});

 

标签:const,跨域,res,app,必考,面试,http,data
From: https://www.cnblogs.com/zx618/p/18326830

相关文章

  • Python面试宝典第19题:最小路径和
    题目        给定一个包含非负整数的mxn网格grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。        示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总......
  • 2024AGI面试官 常问的问题以及答案(附最新的AI大模型算法面试大厂必考100题 )
    前言在这个人工智能飞速发展的时代,AI大模型已经成为各行各业创新与变革的重要驱动力。从自动驾驶、医疗诊断到金融分析,AI大模型的应用场景日益广泛,为我们的生活带来了前所未有的便捷。作为一名程序员,了解并掌握AI大模型的相关知识,无疑将大大提升我们的竞争力。在这个充满......
  • Android笔试面试题AI答之控件Views(6)
    答案来着文心一言,仅供参考目录1.简述什么是RemoteViews?使用场景有哪些?RemoteViews的特性使用场景总结2.获取View宽高的几种方法?1.在`onWindowFocusChanged`方法中获取2.使用`ViewTreeObserver.OnGlobalLayoutListener`3.使用`ViewTreeObserver.OnPreDrawListene......
  • 面试官:说说单点登录都是怎么实现的?
     在数字化时代,用户账户安全和便捷体验成为了众多互联网产品设计的重要考量。       而“单点登录”(SingleSign-On,SSO)作为提升用户体验、简化登录流程的关键技术,已经成为各类企业应用的标准配置。       那么,当你在面试现场被问到‘单点登录是如何实现的?’,......
  • 功能测试面试没人要了!自动化测试如何入门?
    对于我来说,我做的是web端的测试,做测试也有好几个年头了,每次都是使用手工测试的话,一直是做重复性的工作,既枯燥又繁琐,所以我在两年前自己使用java语言写了一系列的自动化测试脚本,利用的框架是java+testng+reportng+selenium,这个框架在项目中基本可用了。不过最近由于公司项目发......
  • 测试面试宝典(三十一)—— 接口测试用例的编写要点有哪些?
    以下是接口测试用例编写的要点:1.基本信息•明确接口的名称、版本、调用方式(如HTTP、RPC等)以及接口的功能描述。2.输入参数•覆盖各种合法和非法的输入值,包括必填项、可选项、空值、特殊字符、超长字符串等。•考虑不同数据类型(如整数、浮点数、字符串、布尔值等)的......
  • 测试面试宝典(三十)—— 请你对朋友圈点赞功能进行测试
    首先,从功能方面考虑:1.测试正常点赞操作,检查是否能成功点赞,点赞后是否有相应的提示,如“点赞成功”。2.多次点赞同一内容,观察是否有正确的处理,例如只记录一次点赞。3.取消点赞功能,验证取消后点赞数是否相应减少,且再次点赞能否正常操作。其次,从性能方面:1.测试大量用户同......
  • Redis缓存面试问题解析:如何有效管理缓存失效策略?
    在技术面试中,Redis缓存是一个常见的话题。面试官往往会考察候选人对缓存机制的理解以及在实际场景中的应用能力。本文将探讨一个在Redis缓存面试中经常被问到的问题,并深入解析其背后的概念和解决方案。面试问题:如何管理Redis缓存的失效策略?问题描述:在高并发的web应用中,缓存是提......
  • 面试题:简单介绍一下快速失败和安全失败。简单介绍一下快速失败和安全失败和集合类的关
    一.简单介绍一下快速失败和安全失败Java中的快速失败(Fast-fail)和安全失败(Safe-fail)是两种异常处理机制,它们在处理程序运行过程中出现的错误或异常时有所不同。1.快速失败(Fast-fail):快速失败是一种异常处理机制,当程序运行过程中遇到一个错误或异常时,它会立即终止程序的......
  • 面试场景题系列--(2)短 URL 生成器设计:百亿短 URL 怎样做到无冲突?--xunznux
    文章目录面试场景题:短URL生成器设计:百亿短URL怎样做到无冲突?1.需求分析2.短链接生成算法2.1自增法2.2散列函数法2.3预生成法3.部署模型3.1其他部署方案4.设计4.1重定向响应码4.2短URL预生成文件及预加载4.3用户自定义短URL4.4URLBase64编码4.5UR......