Hello,
I am trying to run a docker container with spring-boot + react app and it building with no issue and working fine locally, but after deploying it on render it throws an error.
It’s a Cors error, any idea how to fix this issue?
FrontEnd :
import axios from ‘axios’;
export const addLinks = async (link, enable) => {
const baseUrl = process.env.REACT_APP_BASE_URL;
const url = `${baseUrl}/urlData/insert`;
const list = []
list.push(link)
let response;
try {
response = await axios.post(url, list, {
headers: {
'Content-Type': 'application/json',
},
params: {
'jsEnable': enable
},
date: list
});
// return response;
} catch (error) {
console.error('Error fetching images:', error);
throw error;
}
finally {
return response;
}
};
Backend :
Controller
@RestController
@RequestMapping(“/urlData”)
@CrossOrigin(origins = “", allowedHeaders = "”, maxAge = 3600L, methods = {RequestMethod.GET, RequestMethod.OPTIONS, RequestMethod.POST})
public class UrlDataController {
@Autowired
private UrlDataService urlDataService;
@PostMapping("/insert")
public ResponseEntity<?> insertBulk(@RequestBody List<String> urls, @RequestParam("jsEnable") Boolean jsEnable) {
MyLogger.info("LINK ADDED " + urls.get(0) + " AND JS ENABLE " + jsEnable);
UrlData data = null;
try {
data = urlDataService.getData(urls, jsEnable);
} catch (Exception e) {
return ResponseEntity.internalServerError().body("SOMETHING WENT WRONG");
}
if (data == null) {
return ResponseEntity.status(204).build();
}
return ResponseEntity.status(200).build();
}
@GetMapping("/getTags")
public ResponseEntity<?> getAllTags() {
MyLogger.info("TAGS REQUESTED");
List<String> list = urlDataService.getAllTags();
return ResponseEntity.ok().body(list);
}
@GetMapping("/search/{keyword}")
public ResponseEntity<?> search(@PathVariable String keyword) {
MyLogger.info("KEYWORD SEARCH REQUESTED");
return ResponseEntity.ok().body(urlDataService.searchString(keyword));
}
@GetMapping("/getImages")
public ResponseEntity<?> getImages() throws Exception {
MyLogger.info("GET IMAGES REQUESTED");
return ResponseEntity.of(Optional.ofNullable(urlDataService.images()));
}
@GetMapping("/getData")
public ResponseEntity<?> getData() throws IOException {
MyLogger.info("GET ZIP FILE REQUESTED");
Resource file = urlDataService.sendZip();
if (file == null) {
MyLogger.warn("REQUEST NOT COMPLETED");
return ResponseEntity.status(500).build();
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", "data.zip");
return ResponseEntity.ok()
.headers(headers)
.body(file);
}
}
Config
package com.url.extractor.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.List;
@Configuration
@EnableWebMvc
public class Config implements WebMvcConfigurer {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RateLimitInterceptor()).addPathPatterns("/**", "/urlData/getData");
}
}
####DockerFile
Stage 1: Setup Nginx and Node.js
FROM nginx:alpine
Update package repository and install required packages
RUN apk update &&
apk add --no-cache openjdk17 supervisor
Set the working directory for the application
WORKDIR /app
Copy build files to nginx directory
COPY /url_exct_frontend/build /usr/share/nginx/html
Copy jar file to app directory
COPY target/*.jar app.jar
Allow executable permissions to the jar file
RUN chmod +x app.jar
Copy supervisord configuration file
COPY supervisord.conf /etc/supervisord.conf
Expose port 80
EXPOSE 80 8080
Start supervisord to manage Java application and Nginx server
CMD [“/usr/bin/supervisord”, “-c”, “/etc/supervisord.conf”]