So I wanted to create a web application in angular that, amongst other things, shows pdf files to the user. The pdf files are stored in a database, and are retreived by and sent to the user with a Spring Boot backend. When running on a local machine, everything was fine. However, issues arose once I wanted to run it in a ngnix based docker image. The error log keeps saying there's an issue with MIME types. Note: this is specifically for the part loading in the PDF, everything else seems to function just fine.
The Error log:
main-7X4J5JFT.js:50 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
Now, I have tried a lot - and I mean A LOT - of different sulotions over a span of 3 full days. I might be missing something very important, but I just really don't get what I should change to my project. For reference, here is the nginx.conf:
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri /index.html;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|otf|webmanifest|txt|xml)$ {
expires 6M;
access_log off;
add_header Cache-Control "public";
}
location ~* \.pdf$ {
add_header Content-Type application/pdf;
expires 1M;
access_log off;
add_header Cache-Control "public";
}
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
}
This is my dockerfile:
# Step 1: Use a Node.js base image to build the app
FROM node:22.13.0-alpine AS build
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package.json package-lock.json ./
# install project dependencies
RUN npm install
RUN npx ngcc --properties es2025 browser module main --first-only --create-ivy-entry-points
# Copy the entire project to the container
COPY . .
# Build the Angular app
RUN npm run build
# Step 2: Use an NGINX base image to serve the app
FROM nginx:stable
# Copy built Angular app from the build stage to the NGINX HTML folder
COPY --from=build /app/dist/cyberlab-frontend/browser /usr/share/nginx/html
RUN chmod -R 755 /usr/share/nginx/html
# Copy custom Nginx configuration file
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose the default NGINX port
EXPOSE 80
This is the part in the backend that handles the sending of the pdf file:
@RateLimiter(name = "default")
@GetMapping("/fetchLab")
public ResponseEntity<byte[]> getLab(@RequestParam long labId, @RequestParam String labName) {
try {
Optional<LabDTO> labDetails = this.labService.getLabById(labId);
if (labDetails.isEmpty()) {
throw new Exception("Could not find specified lab");
}
if (!labDetails.get().name().equals(labName)){
throw new Exception("LabId and Labname do not match");
}
byte[] pdf = labDetails.get().pdf();
String fileName = labDetails.get().name() + ".pdf";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDisposition(ContentDisposition.inline().filename(fileName).build());
return new ResponseEntity<>(pdf, headers, HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(String.format("{\"success\":false,\"message\":\"%s\"}", e.getMessage()).getBytes());
}
}
And last, the frontend method that should handle the viewer of the pdf file. Please note, in my HTML I am using a ngx-extended-pdf-viewer:
ngOnInit(): void {
this.labId = this.route.snapshot.params['labId'];
this.labName = this.route.snapshot.params['labName'];
this.labService.fetchLab(this.labId!, this.labName!).subscribe({
next: (file: Blob) => {
console.log('Received Blob Size:', file.size); // Log Blob size
if (file.size > 0) {
this.pdfFile = URL.createObjectURL(file); // Pass this URL to your PDF viewer
} else {
window.alert('Received an empty PDF file');
}
},
error: (err) => {
console.error('Failed to fetch the lab:', err);
window.alert('Page does not exist or an error occurred.');
}
});
}
Re edit. You have named the library you are using. The issue you describe is the very first thing on its Troubleshooting page! It even gives you a copy/paste solution for nginx.
You need to think less about the end goal and more about what the error message is telling you.
main-7X4J5JFT.js:50
So the error occurred in the file main-7X4J5JFT.js on line 50.
Look at line 50 of that file and see what it is doing
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream".
So it tried to load a JavaScript module and the server responded with something which had Content-Type: application/octet-stream
Look in the Network tab of your browser's developer tools. Find the request for that file. It will be one with that content-type. It will probably have its file name on line 50 of main-7X4J5JFT.js.
Note that this has nothing to do with PDFs. It's all about loading your (presumably) third-party library.
Given that I don't have access to the information you would get from doing that debugging, the rest of this answer is an informed guess.