MST

星途 面试题库

面试题:Angular应用跨域问题在静态服务器部署下的深度分析与解决方案

在将Angular应用部署到静态服务器后,与后端API进行交互时出现了跨域问题。请详细分析跨域产生的原因,从浏览器同源策略、Angular应用本身以及静态服务器配置等多方面进行阐述,并给出至少两种不同层面(如前端、后端、服务器配置等)的有效解决方案及实现细节。
37.6万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

跨域产生原因

  1. 浏览器同源策略:同源策略是浏览器的一个安全功能,它限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这里的“源”由协议、域名和端口号组成,只有当这三者完全相同时,才属于同一个源。例如,http://example.com:80https://example.com:80 由于协议不同,不是同源;http://example.com:80http://example.com:81 由于端口不同,也不是同源。当Angular应用(假设运行在 http://localhost:4200)向后端API(假设运行在 http://api.example.com)发起请求时,就会触发跨域问题,因为它们不属于同一个源。
  2. Angular应用本身:Angular应用在发送HTTP请求时遵循浏览器的同源策略。虽然Angular提供了强大的HTTP客户端模块(如 @angular/common/http),但它本身并没有绕过同源策略的能力。如果没有适当的配置,直接向不同源的API发送请求就会遇到跨域限制。
  3. 静态服务器配置:如果静态服务器没有正确配置允许跨域请求,也会导致跨域问题。例如,常见的静态服务器如Nginx或Apache,默认情况下不会允许跨域请求。如果没有配置相应的跨域规则,浏览器会阻止从静态服务器加载的Angular应用向不同源的API发起请求。

解决方案及实现细节

  1. 前端层面(使用代理)
    • 原理:在开发环境中,通过配置代理服务器,将所有跨域请求转发到后端API,这样对于浏览器来说,请求就变成了同域请求。
    • 实现细节(以Angular CLI为例)
      • 创建一个代理配置文件,例如 proxy.conf.json
      {
        "/api": {
          "target": "http://api.example.com",
          "secure": false,
          "changeOrigin": true
        }
      }
      
      • 这里 /api 表示匹配以 /api 开头的请求路径,target 是后端API的实际地址,secure 设置为 false 表示允许通过HTTP协议转发请求,changeOrigin 设置为 true 表示修改请求头中的 Origin 字段,使其与目标服务器一致。
      • package.json 文件中,修改 start 脚本:
      {
        "scripts": {
          "start": "ng serve --proxy-config proxy.conf.json"
        }
      }
      
      • 这样在开发时运行 npm start,Angular应用就会通过代理服务器向后端API发送请求,避免跨域问题。需要注意的是,此方法主要用于开发环境,生产环境需要在服务器端进行配置。
  2. 后端层面(设置CORS)
    • 原理:后端服务器通过设置响应头来告诉浏览器允许哪些源的请求,从而绕过浏览器的同源策略限制。
    • 实现细节(以Node.js + Express为例)
      • 安装 cors 模块:npm install cors
      • 在Express应用中引入并使用 cors 中间件:
      const express = require('express');
      const cors = require('cors');
      const app = express();
      
      app.use(cors());
      
      // 其他路由和中间件配置
      app.listen(3000, () => {
        console.log('Server running on port 3000');
      });
      
      • 上述代码中,app.use(cors()) 表示允许所有源的请求。如果需要更细粒度的控制,可以传入一个配置对象:
      app.use(cors({
        origin: 'http://localhost:4200',
        methods: ['GET', 'POST', 'PUT', 'DELETE'],
        allowedHeaders: ['Content-Type']
      }));
      
      • 这里 origin 指定允许的源,methods 指定允许的HTTP方法,allowedHeaders 指定允许的请求头。
  3. 服务器配置层面(以Nginx为例)
    • 原理:在Nginx服务器配置中,添加允许跨域的响应头,从而让浏览器允许跨域请求。
    • 实现细节
      • 编辑Nginx的配置文件(通常在 /etc/nginx/sites - available/ 目录下),找到对应的服务器块(server 块)。
      server {
        listen 80;
        server_name your_domain.com;
      
        location / {
          add_header 'Access - Control - Allow - Origin' '*';
          add_header 'Access - Control - Allow - Methods' 'GET, POST, PUT, DELETE, OPTIONS';
          add_header 'Access - Control - Allow - Headers' 'DNT,X - User - Token,X - CSRF - Token,Keep - Alive,User - Agent,X - Requested - With,If - Modified - Since,Cache - Control,Content - Type,Content - Range,Range';
      
          if ($request_method = 'OPTIONS') {
            return 204;
          }
      
          # 其他Nginx配置,如静态文件服务等
        }
      }
      
      • add_header 'Access - Control - Allow - Origin' '*' 表示允许所有源的请求,如果需要限制,可以将 * 替换为具体的源。add_header 'Access - Control - Allow - Methods'add_header 'Access - Control - Allow - Headers' 分别指定允许的HTTP方法和请求头。if ($request_method = 'OPTIONS') 块用于处理预检请求,直接返回204状态码表示允许跨域。修改完配置文件后,重启Nginx服务使配置生效:sudo systemctl restart nginx