我阅读了我在本网站和其他网站上找到的信息。我以为会很简单,但 TypeError: Failed to fetch 错误在各种情况下仍然存在。我正在描述这种情况,希望
我阅读了我在本网站和其他网站上找到的信息。我以为这很简单,但 TypeError: Failed to fetch 错误在各种情况下仍然存在。我正在描述这种情况,希望有人能指出我的错误。
我的项目是一个 Spring Boot 应用程序(用于教育目的)。项目的主要部分部署在端口 8080 上。HTML 页面也包含在该项目内。页面有两个部分:订阅更改和个人数据更改。更改个人数据时前端不会出现任何错误,因为来自前端的请求会发送到端口 8080 上的控制器。
但是,当更改订阅时,前端的请求会发送到端口 8080 上的订阅更改控制器,该控制器又会调用支付控制器(也在端口 8080 上)。支付控制器将数据发送到在端口 8081 上运行的模拟银行服务器。订阅按预期更改,但响应未返回到前端,而是出现 TypeError:无法获取错误。
我已经在端口 8080 和 8081 上配置了 CORS 设置(同时和单独配置),并且我已在所有端口上为控制器添加了注释(同时和单独配置)。我还修改了 WebSecurityConfig 设置。尽管进行了所有这些尝试,但问题仍未解决。
我已将所有更改恢复到初始状态(错误出现之前)。目前,我的代码中唯一提到 CORS 的地方是我的 WebSecurityConfig。当然,当尝试在 WebSecurityConfig 中添加 WebMvcConfigurer 时,.cors().disable() 要么已启用,要么不存在。我尝试了不同的选项,但问题没有解决。
我希望得到您的帮助和解释,特别是针对我的情况。
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig {
private final JWTTokenConfig jwtTokenConfig;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors().disable()
.authorizeRequests(authorize -> authorize
.antMatchers("/register","/host_page", "/login", "/music_files").permitAll()
.antMatchers("/static/**","/images/background.jpg").permitAll()
.antMatchers("/swagger-ui/**", "/swagger-resources/*", "/v3/api-docs/**", "/swagger-ui.html").permitAll()
.antMatchers("/personal_office/**").authenticated()
.antMatchers(HttpMethod.GET, "/main").permitAll()
.antMatchers("/free_subscription").hasAnyRole("FREE", "OPTIMAL", "MAXIMUM", "ADMIN")
.antMatchers("/optimal_subscription").hasAnyRole("MAXIMUM", "OPTIMAL", "ADMIN")
.antMatchers("/maximum_subscription").hasAnyRole("MAXIMUM", "ADMIN")
.antMatchers("/admin_office/**", "/users").hasRole("ADMIN")
.anyRequest().authenticated()
)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore((Filter) jwtTokenConfig, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/static/**", "/styles/**", "/images/**", "/js/**");
}
}
如果需要,我可以提供其余代码,但我相信问题具体出在 CORS 配置设置上,也可能出在 WebSecurityConfig 上。
添加了更多代码。该脚本向端口 8080 上的服务器发送请求。
function updateSubscription(subscriptionName) {
const jwtToken = getCookie('JWT_TOKEN');
if (!jwtToken) {
console.error('JWT token not found');
return;
}
const requestData = {
newSubscription: {
subscriptionName: subscriptionName
}
};
fetch('/personal_office/update_subscription', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestData)
})
.then(response => {
if (!response.ok) {
return response.text().then(text => {
throw new Error(text);
});
}
return response.text();
})
.then(responseMessage => {
displayMessage(responseMessage, 'success');
showSubscriptionOnScreen();
showSubscriptionEndTimeOnScreen();
})
.catch(error => {
console.error('Failed to update subscription: ', error);
displayMessage(error.message, 'error');
});
}这是这个控制器。它在端口 8080 上运行。
@PutMapping("/update_subscription")
public ResponseEntity<String> updateSubscription(@RequestBody UpdateSubscriptionDTO request,
@RequestHeader("Authorization") String jwtToken) {
long userPhoneNumber = userService.getCurrentUserPhoneNumber(jwtToken);
log.debug("Current user's phone number retrieved: {}", userPhoneNumber);
try {
User user = userRepository.findByPhoneNumber(userPhoneNumber);
Subscription subscription = subscriptionRepository.findBySubscriptionNameIgnoreCase(request.getNewSubscription().getSubscriptionName());
if (subscription == null) {
throw new NoSuchElementException("Subscription " + request.getNewSubscription().getSubscriptionName() + " not found");
}
TransactionDTO transactionDTO = TransactionDTO.builder()
.outputCardNumber(user.getUserBankCard().getCardNumber())
.sum(subscription.getSubscriptionPrice())
.cardExpirationDate(user.getUserBankCard().getCardExpirationDate())
.cvv(user.getUserBankCard().getCvv()).build();
ResponseEntity<String> paymentResponse = paymentController.payment(transactionDTO);
if (paymentResponse.getStatusCode().is2xxSuccessful()) {
userService.updateSubscription(userPhoneNumber, request);
log.info("Subscription for user with phone number {} updated successful", user.getPhoneNumber());
String responseMessage = "Subscription " + subscription.getSubscriptionName() + " successful activated";
return ResponseEntity.ok(responseMessage);
} else if (paymentResponse.getStatusCode() == HttpStatus.BAD_REQUEST) {
String errorMessage = paymentResponse.getBody();
log.warn("Payment failed: {}", errorMessage);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorMessage);
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Payment failed");
}
} catch (NoSuchElementException e) {
log.warn(e.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
} catch (Exception e) {
log.error("An error occurred while updating subscription", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred");
}
}
它将数据发送到该控制器(该控制器也在端口 8080 上运行)。
@PostMapping
public ResponseEntity<String> payment(@RequestBody TransactionDTO request) {
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String currentTransactionData = "current_transaction";
long recipientBankCardNumber = paymentRecipientDataRepository.findByTransactionalNameIgnoreCase(currentTransactionData)
.getRecipientBankCard().getBankCardNumber();
BigDecimal paymentPrice = request.getSum();
String bankUrlTransaction = paymentRecipientDataRepository.findByTransactionalNameIgnoreCase(currentTransactionData)
.getBankTransactionData().getBankUrlTransaction();
TransactionDTO transactionDTO = TransactionDTO.builder()
.outputCardNumber(request.getOutputCardNumber())
.targetCardNumber(recipientBankCardNumber)
.sum(paymentPrice)
.cardExpirationDate(request.getCardExpirationDate())
.cvv(request.getCvv()).build();
Mono<ResponseEntity<String>> bankResponseMono = webClientBuilder.build()
.post()
.uri(bankUrlTransaction)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(transactionDTO)
.retrieve()
.onStatus(HttpStatus.BAD_REQUEST::equals, clientResponse -> clientResponse.bodyToMono(String.class)
.flatMap(errorBody -> Mono.error(new IllegalArgumentException("Payment failed: " + errorBody))))
.toEntity(String.class);
ResponseEntity<String> bankResponse = bankResponseMono.block();
return bankResponse;
} catch (IllegalArgumentException e) {
log.error(e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
} catch (Exception e) {
log.error("An unexpected error occurred", e);
throw new IllegalStateException("An unexpected error occurred", e);
}
}
然后付款将数据发送到在端口 8081 上运行的控制器。订阅在数据库中更新,并在网页上更改(如果刷新页面),但前端服务器未收到任何响应,我在控制台中看到 TypeError:无法获取错误。可能是什么原因?
在此处输入图片描述