WebブラウザからSORACOMエントリポイントを叩けないこともあると学んだ日

## やりたかったこと
AWS AmplifyでホストするNext.jsのWebアプリがあります。
SORACOM SIMを挿したデバイスのブラウザでこのWebアプリを起動し、SORACOM　Funkのエントリポイントを叩いてLambdaに接続したかったです。ちなみにHTTP通信には、Axiosというライブラリを使いました。

![スクリーンショット 2023-10-18 22.08.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/99b95329-8f3e-3958-ce86-113adcde2377.png)

## 問題

エラーに直面しました！
そして最終的にこのエントリポイントは叩けませんでした。

![スクリーンショット 2023-10-07 16.59.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/be80b138-b386-4f47-038c-37159f33332d.png)

>- [blocked] The page at https://foo.bar.amplifyapp.com/hoge was not allowed to display insecure content from http://funk.soracom.io/. (675-73bf76adf43e6dc1.js, line 5)
>- Not allowed to request resource
>- XMLHttpRequest cannot load http://funk.soracom.io/ due to access control checks.
>- Error occurred: – B {stack: "B@https://foo.bar.amplifyapp.com/…ext/static/chunks/675-73bf76adf43e6dc1.js:5:82357", message: "Network Error", name: "AxiosError", …}`

GPTくんに聞きました。

- 最初のエラーは、HTTPSで提供されるページが、HTTPプロトコルを使用して外部リソースにアクセスしようとしているため、ブラウザにブロックされたことを示しています。
- XMLHttpRequest cannot load http://funk.soracom.io/ due to access control checks.というエラーは、CORSポリシーにより、クロスオリジンリクエストがブロックされたことを示しています。CORSポリシーは、ウェブページが他のドメインのリソースに安全にアクセスできるようにブラウザに指示するものです。

HTTPとHTTPSが混在していること、CORSの2点が問題のようです。

## 試みたこと

### 1. HTTPとHTTPSの混在対策

Webアプリは要件的にどうしてもHTTPSの必要がありました。セキュリティ要件があったのと、カメラにアクセスするにはHTTPSが必須のようです。一方ソラコムのエントリポイントはhttpのみです。
上のエラーではErrorではなく、Warningだったので、問題ないかもと思ったのですが、PCブラウザではErrorになっていました。（SORACOM SIM挿してないのでそもそもうまくいきませんが）

![SCR-20231008-soss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/3fa56851-c09f-4ed4-acde-df050d25e48b.png)

つまり、今振り返って考えると、後述のCORSを見るまでもなく、この時点で既に詰んでいたとも言えます（笑）

### 2. CORS対策

### 2-1. メタデータサービスを使ってみる

ドキュメントはこちら。

https://users.soracom.io/ja-jp/docs/air/use-metadata/

[許可するオリジン]にアプリのオリジンのURLを入れてみましたが解決に至りませんでした。

![SCR-20231008-tbhf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/5e8cf55a-f9e7-1973-7fe6-8aebbd50a911.png)

### 2-2. Amplifyのカスタムヘッダーを設定

次はAmplify側をいじってみます。
カスタムヘッダーを設定してみました。

![スクリーンショット 2023-09-25 17.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/89fdf994-dd0f-9940-cac6-c51ec83b173c.png)

![スクリーンショット 2023-09-25 18.17.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/beba80a2-a13b-07f6-4e9c-5b66ab52b55c.png)

結果がこちら。これもダメでした。

![スクリーンショット 2023-09-25 17.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/4a8150dc-2002-8627-87ba-878cca88fbf8.png)


![SCR-20231008-tgkj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/d4496af4-e68e-5f7a-2fdd-5d8bad9340ea.png)


#### 2-3. リクエストのヘッダーにAccess-Control-Allow-Originを入れる。

CORSを許可するには、レスポンス側の設定をしてあげないといけないのは、過去に経験からわかってはいたものの、藁をも掴む思いで試してみました。案の定何の解決にもなりませんでした :sweat: 

過去の経験↓

https://qiita.com/kakudaisuke/items/91e781e532a3cd300a55

```react
import axios from "axios";

const postToSoracom = async (val: string) => {
  interface Payload {
    val: string;
  }
  const payload: Payload = {
    val,
  };
  const url = "http://funk.soracom.io";
  const headers = {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*", // これを入れてみた
  };
  const response = await axios.post(url, payload, {
    headers: headers,
  });
  return response;
};
```


### 2-4. サーバーサイドからAPIを叩く

フロントのブラウザから叩くのが問題なら、Next.jsだしサーバーサイドから叩けばあるいは...という話もありましたが、うまくいかず。

ただ、ここはあまり深掘りできなったので、完全にダメだったとは言い切れないです。

サーバーサイドから叩こうとして参照したサイトはこの辺。

https://aws.amazon.com/jp/blogs/news/next-js-api-routes-with-aws-amplify/

https://reffect.co.jp/react/next-js-api-route/


## 最後に

今回の失敗から色々学ぶことができました。

また、余談ですがスマホでのデバッグで、コンソールを見たい時にこちらの方法でうまく行きました。
iPhoneとMacをUSBで物理的に接続するのをお忘れなく。

https://qiita.com/yutomaeda5510/items/f78d60038e2af34f67f0