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

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

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

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

googleChromeの検証ツール結果の画像(赤丸部のリクエストがそれに該当)
preflight(OPTIONS Request Mehod)
↓
all(全取得 GET Request Method)
↓
add(POST Request Method)
という順番で実行される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/15a9cd63-81a7-36cd-d031-052c5731c5ea.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を追加しただけです。

修正後のソースコード
```diff_typescript
-   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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/361706cb-1b20-ac0d-228f-fbfa63108bd4.png)

preflight(OPTIONS Request Mehod)
↓
add(POST Request Method)
↓
all(全取得 GET Request Method)

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

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

https://developer.mozilla.org/ja/docs/Glossary/Preflight_request


https://qiita.com/nnishimura/items/1f156f05b26a5bce3672