面试题答案
一键面试解决跨域问题的思路
- CORS(跨源资源共享):
- 在服务器端配置允许跨域的请求。对于不同的后端技术栈,有不同的配置方式。例如在Node.js(Express)中,可以使用
cors
中间件。 - 配置
Access - Control - Allow - Origin
等响应头,指定允许跨域请求的源。可以设置为具体的租户子域名,或者*
(但*
在某些场景下有限制,比如涉及到Credentials时不能使用)。
- 在服务器端配置允许跨域的请求。对于不同的后端技术栈,有不同的配置方式。例如在Node.js(Express)中,可以使用
- 代理:
- 在开发环境中,可以使用Angular的
proxy.conf.json
文件进行代理配置。这样在开发过程中,所有跨域请求都会被代理到目标服务器,绕过浏览器的跨域限制。 - 在生产环境,可以使用反向代理服务器(如Nginx或Apache)来代理跨域请求,同样通过配置响应头来解决跨域问题。
- 在开发环境中,可以使用Angular的
调整静态资源缓存策略以适应不同浏览器的方案
- Cache - Control头:
- 对于不同的静态资源类型(如CSS、JS、图片等)设置合适的
Cache - Control
头。例如,对于不经常变动的静态资源(如公共的样式库、脚本库),可以设置较长的缓存时间,如Cache - Control: max - age = 31536000
(一年)。 - 对于可能会频繁变动的资源,设置较短的缓存时间,如
Cache - Control: max - age = 3600
(一小时)。
- 对于不同的静态资源类型(如CSS、JS、图片等)设置合适的
- ETag:
- 服务器为每个静态资源生成唯一的ETag值。当浏览器请求资源时,服务器根据请求头中的
If - None - Match
字段与当前资源的ETag值进行比较。如果匹配,说明资源未变动,服务器返回304状态码,浏览器使用本地缓存。
- 服务器为每个静态资源生成唯一的ETag值。当浏览器请求资源时,服务器根据请求头中的
- Vary头:
- 当静态资源的缓存策略可能因某些请求头(如
Accept - Encoding
)不同而不同时,设置Vary
头。例如,如果服务器根据浏览器是否支持gzip压缩来返回不同压缩格式的资源,可以设置Vary: Accept - Encoding
,这样浏览器会根据该头来正确缓存资源。
- 当静态资源的缓存策略可能因某些请求头(如
完整解决方案及相关配置代码
1. 解决跨域问题(以Node.js + Express为例)
const express = require('express');
const cors = require('cors');
const app = express();
// 配置CORS
app.use(cors({
origin: ['http://tenant1.example.com', 'http://tenant2.example.com'], // 替换为实际租户子域名
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content - Type', 'Authorization']
}));
// 其他路由和中间件配置
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
2. 配置静态资源缓存策略(以Node.js + Express为例)
const express = require('express');
const app = express();
// 设置静态资源中间件并配置缓存
app.use('/static', express.static('public', {
maxAge: 31536000, // 缓存一年
setHeaders: (res, path) => {
if (path.endsWith('.html')) {
res.set('Cache - Control','no - cache, no - store, must - revalidate');
} else if (path.endsWith('.js') || path.endsWith('.css')) {
res.set('Cache - Control','public, max - age = 31536000');
}
}
}));
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
3. Angular开发环境代理配置(proxy.conf.json)
{
"/api": {
"target": "http://your - backend - server.com",
"secure": false,
"changeOrigin": true
}
}
在angular.json
中配置代理:
{
"architect": {
"serve": {
"proxyConfig": "./proxy.conf.json",
// 其他配置
}
}
}
4. Nginx反向代理及跨域和缓存配置
server {
listen 80;
server_name tenant1.example.com;
location / {
proxy_pass http://your - angular - app - server;
proxy_set_header Host $host;
proxy_set_header X - Real - IP $remote_addr;
proxy_set_header X - Forwarded - For $proxy_add_x_forwarded_for;
proxy_set_header X - Forwarded - Proto $scheme;
# 解决跨域问题
add_header Access - Control - Allow - Origin http://tenant1.example.com;
add_header Access - Control - Allow - Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access - Control - Allow - Headers 'Content - Type, Authorization';
# 静态资源缓存配置
location ~* \.(css|js|png|jpg|gif)$ {
expires 365d;
access_log off;
}
}
}