MST

星途 面试题库

面试题:Angular跨域问题在环境搭建后的解决方案

假设你已经成功搭建好Angular开发环境,在与后端进行交互时遇到了跨域问题。请详细说明你可以采取哪些措施来解决这个问题,例如在Angular项目配置层面、后端服务器配置层面分别如何处理,以及每种方案的优缺点。
29.4万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

Angular项目配置层面

  1. 使用代理(Proxy)
    • 操作方法:在Angular项目根目录下创建一个proxy.conf.json文件(文件名可自定义),内容类似如下:
{
  "/api": {
    "target": "http://backend-server-url:port",
    "secure": false,
    "changeOrigin": true
  }
}

这里/api是你后端API的前缀,target是后端服务器的实际地址。然后在package.json文件的scripts部分添加 "start": "ng serve --proxy - config proxy.conf.json"。这样启动项目时,Angular会将以/api开头的请求代理到后端服务器,从而绕过跨域问题。

  • 优点
    • 简单易用,不需要后端配合修改配置,对前端开发人员友好。
    • 开发环境下快速解决跨域,方便前后端联调。
  • 缺点
    • 只适用于开发环境,生产环境无法使用。因为代理是在开发服务器(ng serve)层面实现的,生产环境部署后不存在这个代理机制。

后端服务器配置层面

  1. CORS(跨域资源共享)
    • 操作方法:不同后端语言实现方式略有不同。以Node.js + Express为例,安装corsnpm install 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');
});

在Java Spring Boot项目中,可以通过配置WebMvcConfigurer来实现:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
              .allowedOrigins("*")
              .allowedMethods("GET", "POST", "PUT", "DELETE")
              .allowedHeaders("*");
    }
}
  • 优点
    • 通用解决方案,适用于开发环境和生产环境。
    • 配置灵活,可以针对不同的源、方法、头进行细粒度控制。
  • 缺点
    • 需要后端开发人员配合修改配置,如果后端代码结构复杂,可能配置过程会比较繁琐。
    • 安全性方面,如果配置不当(如允许所有源allowedOrigins("*")),可能存在一定的安全风险,比如被恶意跨域请求。
  1. JSONP(JSON with Padding)
    • 操作方法:JSONP只支持GET请求。后端返回的数据需要包裹在一个回调函数中。前端使用HttpClientHttp模块进行请求时,要设置特殊的请求头和回调函数名。以Angular的HttpClient为例:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class JsonpService {
  constructor(private http: HttpClient) {}

  getJsonpData() {
    const callbackName = 'jsonpCallback';
    const url = `http://backend - server - url/api/data?callback=${callbackName}`;
    return this.http.jsonp(url, callbackName);
  }
}

后端(以Node.js + Express为例)代码如下:

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

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

app.listen(3000, () => {
  console.log('Server running on port 3000');
});
  • 优点
    • 兼容性好,能在一些不支持CORS的旧浏览器中使用。
    • 不需要复杂的服务器配置(相对于CORS在一些复杂场景下)。
  • 缺点
    • 只支持GET请求,适用场景有限。
    • 安全性较差,容易受到JSONP劫持攻击,因为可以通过构造恶意URL来调用JSONP接口。