Chrome Fetch Request to 127.0.0.1 Not Returning Expected 304 Status in Spring Boot Application

23 Views Asked by At

Problem Summary:

In my Spring Boot application, I'm facing an issue where fetch requests to 127.0.0.1 via JavaScript within a returned view are not behaving as expected in Chrome. The second fetch request should return a 304 status due to ETag matching, but it returns 200 instead. This issue does not occur when using the browser URL directly or with the localhost domain.

Detailed Description:

Context: My application uses ETag headers for caching responses. A 304 response is expected on the second request if the content hasn't changed. Specific Issue:

When I make a fetch request to 127.0.0.1 from JavaScript code within a Spring Boot returned view, the second request in Chrome incorrectly returns a 200 status, not the expected 304.

However, when the same URL (127.0.0.1) is entered directly in the browser, it behaves correctly, returning a 304 on the second request.

Requests to localhost work as expected, returning a 304 status on the second request in all scenarios.

This issue seems to be specific to Chrome; other browsers (Firefox, Safari) return the correct 304 status for both localhost and 127.0.0.1.

What I've Tried: Investigating the difference between localhost and 127.0.0.1, especially regarding how Chrome handles these domains.

Searching for Chrome-specific behaviors or settings that might affect how fetch requests are handled within JavaScript.

Questions:

  1. Why does Chrome return a 200 status for fetch requests to 127.0.0.1 within a Spring Boot returned view, despite the server returning 304?

  2. What is the significant difference in handling between direct browser URL entry and JavaScript fetch requests in Chrome?

  3. How can I ensure consistent ETag-based response handling across different domains and request methods in Chrome?

Additional Context:

The issue is observed in a Spring Boot application, with JavaScript fetch requests within a returned view. I am experiencing this in Chrome version 120.0.6099.10 (arm64) Here is a snippet of the JavaScript code making the fetch request:

document.addEventListener('DOMContentLoaded', (event) => {
    fetchData(1);
    fetch("http://127.0.0.1:8080/api/templates/208")
        .then(res => res.json())
        .then(body => console.log(body));
});
@Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
       
        chain.doFilter(request, response);
    }
@Override
    @Transactional(readOnly = true)
    @Cacheable(value = "mockupTemplate", key = "#id")
    public MockupTemplateReadResponse findOne(long id) {
        return customRepository.getOne(id).orElseThrow(() -> new IllegalArgumentException("Id: " + id + " 는 존재하지 않는 아이디 입니다."));

    }
@GetMapping("/{id}")
    public ResponseEntity<MockupTemplateReadResponse> findMockupTemplate(@PathVariable Long id,
                                                                         @RequestHeader(name = "If-None-Match", required = false) Optional<String> ifNoneMatch) {
        MockupTemplateReadResponse response = service.findOne(id);
        String eTag = response.getUpdateTime().toString();
        if (ifNoneMatch.isPresent() && eTag.equals(ifNoneMatch.get())) {
            return ResponseEntity.status(HttpStatus.NOT_MODIFIED).build();
        }
        return ResponseEntity.ok().eTag(eTag).body(response);
    }
0

There are 0 best solutions below