0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

axios postリクエスト実行前にpreflightリクエストが実行され非同期処理ができない async-awaitの処理を増やして解決

Last updated at Posted at 2023-01-04

症状

実現したい動き

ユースケース的には以下の挙動を実現したいです。
1.買い物カゴに商品を追加する(PostMethodでデータベースに追加)
2.データベースから買い物かご情報を取得して更新して画面に表示する。

1の処理を完了したあとに2の処理を実行させたいので非同期処理を使います。

実際の動き

実際のコードでは以下の挙動になり、追加後の画面更新がなされません。
0.PostMethodと同じURIでprefligtMethodが実行される。
1.データベースから買い物かご情報を取得して更新して画面に表示する。(GETMethodでデータベースから情報取得)
2.買い物カゴに商品を追加する(PostMethodでデータベースに追加)
画面更新後にデータベースに追加されるので期待している挙動ができません。

googleChromeの検証ツール結果の画像(赤丸部のリクエストがそれに該当)
preflight(OPTIONS Request Mehod)

all(全取得 GET Request Method)

add(POST Request Method)
という順番で実行される
image.png

開発環境

IDE:VScode

├── @types/node@18.11.15
├── @types/react-dom@18.0.9
├── @types/react@18.0.26
├── axios@1.2.1
├── eslint-config-next@13.0.6
├── eslint@8.29.0
├── next-auth@4.18.7
├── next@13.0.6
├── react-bootstrap@2.7.0
├── react-dom@18.2.0
├── react@18.2.0
├── styled-components@5.3.6
├── styled-jsx@5.1.1
└── typescript@4.9.4

ソースコード

main.tsx
  const [currentCartItems, setCurrentCartItems] = useState<CartItem[]>([]);
  const [jwtAccessToken, setJwtAccessToken] = useState<string | null>();

  const getCartItems = () => {
    cartItemService
      .getCartItems(jwtAccessToken as string)
      .then((response) => {
        // 再レンダリングを防ぐために、レスポンスのデータが変わっている場合のみsetCurrentCartItemsを実行する。
        if (
          (response.data as CartItem[]).toString() !=
          currentCartItems.toString()
        ) {
          setCurrentCartItems(response.data);
          console.log(response.data);
        }

        console.log("cartItems are set");
      })
      .catch((error) => {
        console.log("cartItems are not set");
      });
  };
 let inputProductId: number = 0;
  let inputQuantity: number = 0;

  const addCartItem =  () => {
    const inputCartItem: CartItem = {
      // productId: inputProductId as number, quantity: inputQuantity as number,
      productId: inputProductId as number,
      quantity: inputQuantity as number,
      id: 0,
      customerId: 0,
    };

     cartItemService
      .addProductCart(inputCartItem, jwtAccessToken as string)
      .then((response) => {
        console.log(response.data);
        console.log("cartItems is added");
      })
      .catch((error) => {
        console.log("cartItems are not set");
      });
  };

  // データベースに追加後、データベースから再取得する
  const addCartItemHandler = async () => {
    console.log("jwt" + jwtAccessToken);
    await addCartItem();
    console.log("between addCartItem and getCartItems");
    await getCartItems();
    //addCartItem実行後に getCartItemが実行されない
    // preflightとやらがきて 実際の処理が実行されない
  };

cartItemService.ts

import axios from 'axios';
import { CartItem } from '../types/cartItem';

/**
 * 
 * @remarks SpringBootで作ったAPIを呼ぶ関数
 * 
 * 
 * @param jwtAccessKey 
 * @returns 
 */

export const addProductCart = ({productId,quantity}: CartItem, jwtAccessKey:string) =>{
	return axios.post(`http://127.0.0.1:5000/api/cart/add`
	+ `?productId=` +productId
	+ `&quantity=` +quantity
	,{},
	{ headers : {
		'Authorization': `Bearer ${jwtAccessKey}`,
		'Request-Method' : 'POST',
		'Content-Type': 'application/json',
		'Access-Control-Allow-Origin': 'http://127.0.0.1:5000/*',
		'Access-Control-Allow-Headers': 'accept, accept-language, content-language, content-type',
		'Access-Control-Allow-Credentials': 'true'
	}}
	);
}


//
export const getCartItems =(jwtAccessKey : string)=>{
	return axios.get(`http://127.0.0.1:5000/api/cart/all`,
	{ headers : {
			'Authorization': `Bearer ${jwtAccessKey}`
		}}
	);
}

// 
export const updateQuantity = ({productId,quantity}:CartItem,jwtAccessKey:string) =>{
	return axios.put(`http://127.0.0.1:5000/api/cart/update`
	+ `?productId=` +productId
	+ `&quantity=` +quantity,
	{ headers : {
			'Authorization': `Bearer ${jwtAccessKey}`
	}}
	)
}

export const removeProduct = ({productId}:CartItem, jwtAccessKey:string) =>{
return axios.delete(`http://127.0.0.1:5000/api/cart/remove`
	+`?productId=`+ productId,
	{ headers : {
			'Authorization': `Bearer ${jwtAccessKey}`
	}}
);
}

export const deleteByCustomer = (jwtAccessKey:string) =>{
	return axios.delete(`http://127.0.0.1:5000/api/cart/delete`,
	{ headers : {
			'Authorization': `Bearer ${jwtAccessKey}`
	}}
);
}


対処方法

方針としてはpreflightリクエストのあとにPostリクエストが実行するようにします。
実装方法としては、addCartItemの処理にasync awaitを追加しただけです。

修正後のソースコード

-   const addCartItem =  () => {
+  const addCartItem = async () => { //asyncの理由 preflight処理が発生しても実行順序守らせるために必要
    const inputCartItem: CartItem = {
      // productId: inputProductId as number, quantity: inputQuantity as number,
      productId: inputProductId as number,
      quantity: inputQuantity as number,
      id: 0,
      customerId: 0,
    };

-     cartItemService
+     await cartItemService //awaitの理由 preflight処理が発生しても実行順序守らせるために必要
      .addProductCart(inputCartItem, jwtAccessToken as string)
      .then((response) => {
        console.log(response.data);
        console.log("cartItems is added");
      })
      .catch((error) => {
        console.log("cartItems are not set");
      });
  };

下のソースコードだけでは不十分みたいですね。

main.tsx
  // データベースに追加後、データベースから再取得する
  const addCartItemHandler = async () => {
    console.log("jwt" + jwtAccessToken);
    await addCartItem();
    console.log("between addCartItem and getCartItems");
    await getCartItems();
    //addCartItem実行後に getCartItemが実行されない
    // preflightとやらがきて 実際の処理が実行されない
  };

確認

赤丸部分が確認する場所です
image.png

preflight(OPTIONS Request Mehod)

add(POST Request Method)

all(全取得 GET Request Method)

となっております。よし!期待した動きをしてるな!

参考

COR関わりの現象みたいですね。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?