フロントエンドの React をホストするサーバーとバックエンドの Java (ですよね?) をホストするサーバーは違うと思いますが、とすると当然ドメインが違って、クロスドメインの問題が出ているということではないのですか?
axiosでのGETリクエストが失敗する ERR_CONNECTION_REFUSED
解決したいこと
JavaScript、reactで作ったものでaxiosを使ってGETリクエストを送るとエラーが出ます。
バックエンドはplayで作成しPostgreSQLで作った適当なデータを取得表示するとこまではちゃんとできているんですけど、フロントエンドの方にうまくデータを送れません。
どなたかわかる方がいらっしゃいましたら教えてください。
発生している問題・エラー
//Vital.js:12がaxiosの文がある行です
Vital.js:12
GET http://localhost:9000/api/vital net::ERR_CONNECTION_REFUSED
(匿名) @ Vital.js:12
他 18 件のフレームを表示
Vital.js:17 axios requestに問題があります:
AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
code
:
"ERR_NETWORK"
config
:
{transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}
message
:
"Network Error"
name
:
"AxiosError"
request
:
XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
stack
:
"AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:111803:14)\n at Axios.request (http://localhost:3000/static/js/bundle.js:112255:41)"
[[Prototype]]
:
Error
constructor
:
ƒ AxiosError(message, code, config, request, response)
toJSON
:
ƒ toJSON()
isAxiosError
:
true
[[Prototype]]
:
Object
(匿名) @ Vital.js:17
Promise.catch(非同期)
(匿名) @ Vital.js:15
他 11 件のフレームを表示
該当するソースコード
// http://localhost:3000/vitalというページのコンポーネントがレンダリングされたタイミングで実行されるようにしています。
useEffect(() => {
axios.get('http://localhost:9000/api/vital')
.then(response => {
console.log("データの取得に成功しました。" + response.data)
})
.catch(error => {
console.error("axios requestに問題があります: ", error)
})
}, [])
@RestController
public class VitalController {
@Autowired
//JpaRepositoryを拡張したリポジトリです
private RiyousyaRepository riyousyaRepository;
@GetMapping("/api/vital")
//Riyousyaはname,idのフィールドを持つクラスです
public List<Riyousya> getData() {
//nameのListにしようとしてたらerrorが出たのでとりあえずこのオブジェクトを取得することにしています。
List<Riyousya> riyousyas = riyousyaRepository.findAll();
return riyousyas;
}
}
routes
GET /api/vital VitalController.getData
1Answer
Comments
@rempei
Questionerご回答ありがとうございます。
クロスドメインの問題とはCORSポリシーによりフロントエンドからバックエンドへのリクエストがブロックされていることでしょうか?
CORS はクロスドメインの問題の回避手段の一つなので、ちょっと表現が違うような気がしますが・・・
バックエンドの Java をホストするサーバーで CORS 対応していなければ(もしくはフロント側でプロキシを使ってなければ)間違いなくクロスドメインの問題が出ます。
対応してますか?
@rempei
Questioner@CrossOrigin(origins = "http://localhost:3000")
をコントローラに追加して対応したら
フロントエンドで同じようなエラーとバックエンドでもエラーが出るようになりました。フロントエンドのエラー
Access to XMLHttpRequest at 'http://localhost:9000/api/vital' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Vital.js:17 axios requestに問題があります: AxiosErrorcode: "ERR_NETWORK"config: {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …}message: "Network Error"name: "AxiosError"request: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}stack: "AxiosError: Network Error\n at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:111803:14)\n at Axios.request (http://localhost:3000/static/js/bundle.js:112255:41)"[[Prototype]]: Error (匿名) @ Vital.js:17 :9000/api/vital:1 Failed to load resource: net::ERR_FAILED
バックエンドのエラー
Not found VitalController.getData action not found
エラーメッセージを見る限り CORS 対応がされてないようですが?
@rempei
Questioner@CrossOriginを使ってみても
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); }
}
というものを使ってCORSの設定をしてみてもエラーがなくならないのですがこの設定は普通はどうするのですか?
初めてやるので全然わかっていないのですが見当違いなことをしているのでしょうか?自分は java + play とか触ったこともないのでそれで正しいのか分かりません。
ただ、「java play cors 対応」などをキーワードにしてググってヒットする記事を見ると、
Cross-Origin Resource Sharing
https://www.playframework.com/documentation/ja/2.4.x/CorsFilter"Play は Cross-Origin Resource Sharing (CORS) を実装したフィルタを備えています"
・・・とのことで、上に書いてあることとは違うようですが?
ヒットする記事の中には Access-Control-Allow-Origin: * を応答ヘッダに追加すればいいなんて言うものもありますが、それはあまりに乱暴かつイイカゲンなので無視しましょう。