MST

星途 面试题库

面试题:Angular HttpClient模块文件上传的性能优化与安全考量

在高并发的文件上传场景下,使用HttpClient模块实现文件上传,从性能优化和安全角度出发,需要考虑哪些方面?请详细说明,并提供相应的优化措施和安全策略代码示例。
11.9万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

性能优化方面

  1. 连接池复用:避免每次上传都创建新连接,提高连接利用率。
    • 优化措施:使用PoolingHttpClientConnectionManager来管理连接池。
    • 代码示例
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(20);
CloseableHttpClient httpClient = HttpClients.custom()
       .setConnectionManager(cm)
       .build();
  1. 异步上传:利用异步操作,不阻塞主线程,提高整体吞吐量。
    • 优化措施:使用CloseableHttpAsyncClient进行异步请求。
    • 代码示例
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;

CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
client.start();
HttpPost httpPost = new HttpPost("http://example.com/upload");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File("path/to/file"), ContentType.APPLICATION_OCTET_STREAM, "filename");
httpPost.setEntity(builder.build());
client.execute(httpPost, new FutureCallback<HttpResponse>() {
    @Override
    public void completed(HttpResponse result) {
        // 处理响应
    }

    @Override
    public void failed(Exception ex) {
        // 处理异常
    }

    @Override
    public void cancelled() {
        // 处理取消
    }
});
  1. 优化请求体构建:减少不必要的内存开销。
    • 优化措施:使用MultipartEntityBuilder流式构建请求体,避免一次性加载整个文件到内存。
    • 代码示例
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File("path/to/file"), ContentType.APPLICATION_OCTET_STREAM, "filename");
httpPost.setEntity(builder.build());

安全策略方面

  1. HTTPS 连接:保证数据传输加密。
    • 安全措施:使用支持HTTPS的HttpClient,配置SSL上下文。
    • 代码示例
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

try {
    SSLContext sslContext = SSLContexts.createDefault();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom()
           .setSSLSocketFactory(sslsf)
           .build();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
    e.printStackTrace();
}
  1. 输入验证:防止恶意文件上传。
    • 安全措施:在服务端对上传文件的大小、类型等进行验证。
    • 代码示例
import org.springframework.web.multipart.MultipartFile;

public boolean isValidFile(MultipartFile file) {
    long maxSize = 10 * 1024 * 1024; // 10MB
    if (file.getSize() > maxSize) {
        return false;
    }
    String contentType = file.getContentType();
    if (!contentType.startsWith("image/") &&!contentType.startsWith("application/pdf")) {
        return false;
    }
    return true;
}
  1. 防止CSRF攻击:如果是Web应用,需防范CSRF。
    • 安全措施:在客户端生成并在请求中携带CSRF令牌,服务端进行验证。
    • 代码示例前端(JavaScript示例)
<input type="hidden" id="csrfToken" value="{{csrfToken}}">
<script>
    var csrfToken = document.getElementById('csrfToken').value;
    var formData = new FormData();
    formData.append('_csrf', csrfToken);
    formData.append('file', fileInput.files[0]);
    fetch('http://example.com/upload', {
        method: 'POST',
        body: formData
    });
</script>

后端(Spring示例)

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@RestController
@CrossOrigin
public class UploadController {

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file,
                             @RequestParam("_csrf") String csrfToken) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        CsrfToken csrf = attributes.getRequest().getAttribute(CsrfToken.class.getName());
        if (csrf != null && csrfToken.equals(csrf.getToken())) {
            // 处理文件上传
            return "File uploaded successfully";
        } else {
            return "CSRF token validation failed";
        }
    }
}