iT邦幫忙

0

前端發送ajax是不是就容易會被阻擋呢?403 status code的錯誤

  • 分享至 

  • xImage

前情提要

我目前正在用reurl提供的API來打ajax做一個練習
使用nodeJS的axios沒有問題
實測token是有效的

問題

然而轉換到練習前端的部分 Jquery post出去接收到的卻是403
"invalid token"

我有確認過API是有效的 也沒有打錯的部分

事實上我已經讓瀏覽器的頁面先到同一個網域了
也就是https://api.reurl.cc/  的地方才執行我的jquery腳本
所以已經避免CROS的問題 是可以發送請求的
只是有收不到result

結論分析

所以我猜測的錯誤原因是 畢竟還是從前端瀏覽器送出的
所以可能是有嚴格的審查機制 不允許我從前端發送post才導致的?

node.js的版本(可運作)

const axios = require("axios");
const readline = require("readline");

const apiUrl = "https://api.reurl.cc/shorten";
const apiKey =
  "APIkey這邊是我用我註冊的值";

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.question("請輸入長網址:", (longUrl) => {
  const requestBody = {
    url: longUrl,
  };

  const config = {
    headers: {
      "Content-Type": "application/json",
      "reurl-api-key": apiKey,
    },
  };

  axios
    .post(apiUrl, requestBody, config)
    .then((response) => {
      const { res, msg, short_url } = response.data;
      if (res === "success") {
        console.log(`縮網址:${short_url}`);
      } else {
        console.error(`縮網址 API 回傳錯誤:${msg}`);
      }
    })
    .catch((error) => {
      console.error(`錯誤:${error}`);
    })
    .finally(() => {
      rl.close();
    });
});

jquery程式碼(提供參考)

const apiUrl = "https://api.reurl.cc/shorten";
const apiKey =
  "APIkey這邊是我用我註冊的值";


    const longUrl = "https://github.com/asd8116/URL-shortener";

    const requestBody = {
      url: longUrl,
    };

    const config = {
      headers: {
        "Content-Type": "application/json",
        "reurl-api-key": apiKey,
      },
    };

    $.post(apiUrl, JSON.stringify(requestBody), config)
      .done((response) => {
        const { res, msg, short_url } = response;
        if (res === "success") {
          console.log(`縮網址:${short_url}`);
        } else {
          console.log(`縮網址 API 回傳錯誤:${msg}`);
        }
      })
      .fail((jqXHR, textStatus, errorThrown) => {
        console.log(`錯誤:${errorThrown}`);
      });

以上

希望對於前端與API或前端爬蟲有經驗的前輩們,能分享一下其中的問題,
為何在後端node可以運作的邏輯,同樣轉換到前端且排除CROS,
卻發生問題呢?

或者說也許就放棄從前端執行呢?
討論看看,感謝各位

更新(已解答版本)

const apiUrl = "https://api.reurl.cc/shorten";
const apiKey =
  "自己的api";


    const longUrl = "https://github.com/asd8116/URL-shortener";

    const requestBody = {
      url: longUrl,
    };

    const config = {
      headers: {
        "Content-Type": "application/json",
        "reurl-api-key": apiKey,
      },
    };
$.post({
    url: apiUrl,
    data: JSON.stringify(requestBody),
    headers: {
        "Content-Type": "application/json",
        "reurl-api-key": apiKey,
    },
    dataType: 'json'
}).done((response) => {
        const { res, msg, short_url } = response;
        if (res === "success") {
          console.log(`縮網址:${short_url}`);
        } else {
          console.log(`縮網址 API 回傳錯誤:${msg}`);
        }
      })
      .fail((jqXHR, textStatus, errorThrown) => {
        console.log(`錯誤:${errorThrown}`);
      });
看更多先前的討論...收起先前的討論...
greenriver iT邦研究生 5 級 ‧ 2023-04-19 08:28:55 檢舉
$.post(apiUrl, JSON.stringify(requestBody), config),將JSON.stringify()拿掉?
greenriver iT邦研究生 5 級 ‧ 2023-04-19 08:37:17 檢舉
在猜是因為設定傳送JSON,結果傳送string過去,造成錯誤?
淺水員 iT邦大師 6 級 ‧ 2023-04-19 12:32:07 檢舉
前端也用 axios 試試看吧
淺水員 iT邦大師 6 級 ‧ 2023-04-19 12:45:14 檢舉
另外 jquery 的 post 跟 axois 的 post 參數定義多半是不同的,要確認一下
揮揮手 iT邦研究生 5 級 ‧ 2023-04-19 16:58:32 檢舉
測試前端用axios
在打一次API看看
失敗了就符合你的結論~
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
淺水員
iT邦大師 6 級 ‧ 2023-04-20 16:45:27
最佳解答

補充一下好了,原本以為有人會提的

瀏覽器可以多利用開發者工具(按F12>網路)看一下自己到底發送了什麼東西出去

以下是幾乎沒動原本程式
只是把 jquery 跟 axios 分別做成不同的測試函式
(這邊沒有幫忙除錯,只是在說明要怎麼檢查錯誤)

html 部分

<script src="https://code.jquery.com/jquery-3.6.4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.6/axios.js"></script>
<script src="index.js"></script>

index.js

const apiUrl = "http://localhost";
const apiKey = "The APIkey";
const longUrl = "https://github.com/asd8116/URL-shortener";

function test_JQuery() {
    const requestBody = {
        url: longUrl,
    };

    const config = {
        headers: {
            "Content-Type": "application/json",
            "reurl-api-key": apiKey,
        },
    };

    $.post(apiUrl, JSON.stringify(requestBody), config)
        .done((response) => {
            const { res, msg, short_url } = response;
            if (res === "success") {
                console.log(`縮網址:${short_url}`);
            } else {
                console.log(`縮網址 API 回傳錯誤:${msg}`);
            }
        })
        .fail((jqXHR, textStatus, errorThrown) => {
            console.log(`錯誤:${errorThrown}`);
        });
}

function testAxios() {
    const requestBody = {
        url: longUrl,
    };

    const config = {
        headers: {
            "Content-Type": "application/json",
            "reurl-api-key": apiKey,
        },
    };

    axios
        .post(apiUrl, requestBody, config)
        .then((response) => {
            const { res, msg, short_url } = response.data;
            if (res === "success") {
                console.log(`縮網址:${short_url}`);
            } else {
                console.error(`縮網址 API 回傳錯誤:${msg}`);
            }
        })
        .catch((error) => {
            console.error(`錯誤:${error}`);
        })
        .finally(() => {
            //rl.close();
        });
}

document.addEventListener('DOMContentLoaded', ()=>{
    // 產生按鈕觸發測試
    [test_JQuery, testAxios].forEach(func=>{
        let btn = document.createElement('button');
        btn.textContent = func.name;
        btn.addEventListener('click', func);
        document.body.appendChild(btn);
    });
});

產生的結果如下
(注意:開發者工具中,通常會有個選項可以切換成看原始的格式)

使用 Axios 時

Header

Content-Type: application/json

Body

{"url":"https://github.com/asd8116/URL-shortener"}

使用 jQuery

Header

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

Body

{"url":"https://github.com/asd8116/URL-shortener"}:	""

如果把 JSON.stringfy 拿掉,Body 會變成

url=https%3A%2F%2Fgithub.com%2Fasd8116%2FURL-shortener

結論

  1. 網頁發送訊息遇到問題時,可以用開發者工具看一下發送的內容是不是跟自己想的一樣。
  2. Axois 跟 jQuery 是不同的軟體,在參數的設計上幾乎不大可能一樣,不能直接套。使用這些軟體最好去看一下他們各自的說明文件。
  3. 有空的話建議了解一下不同的格式,以及 Header 與 Body 之間的關係。
淺水員 iT邦大師 6 級 ‧ 2023-04-20 17:38:00 檢舉

也許可以試試看

$.post({
    url: apiUrl,
    data: JSON.stringify(requestBody),
    headers: {
        "Content-Type": "application/json",
        "reurl-api-key": apiKey,
    },
    dataType: 'json'
})
jason07 iT邦新手 5 級 ‧ 2023-04-22 09:42:19 檢舉

好的了解您的意思,謝謝您大費周章解說。
經過您的提點,真的修正成功了。已經選您為最佳解答。
也謝謝其他人的建議分享!

0
揮揮手
iT邦研究生 5 級 ‧ 2023-04-19 16:59:34

測試 前端用axios
再打一次API看看
失敗了就符合你的結論了

假如axios 可以過的話
那可能就是jqeury post 語法要調整這樣

0
Samuel
iT邦好手 1 級 ‧ 2023-04-20 07:45:00

403 - Forbidden A 403 status code indicates that the client cannot access the requested resource. That might mean that the wrong username and password were sent in the request, or that the permissions on the server do not allow what was being asked.

通常可能是infra範疇建議這個可以先嘗試確認
1.權限問題:您可能未經授權訪問該頁面或資源。請檢查您的使用者權限,以確保您有權訪問此資源。您可以檢查您的使用者帳戶是否有足夠的權限,或者您是否必須通過驗證。

2.IP被阻擋:您的IP地址可能被阻擋,這可能是由於違反網站的規則或防火牆設置所導致。您可以嘗試使用另一個網路連線或與網站的管理員聯繫以解決此問題。

3.代理伺服器設定問題:如果您使用代理伺服器連線,則可能會出現403錯誤。請檢查您的代理伺服器設定,以確保它們正確。

常見status code分類
https://coolmandiary.blogspot.com/2021/12/aspnet-webapi2003mvcwebapipostmanhttpve.html

jason07 iT邦新手 5 級 ‧ 2023-04-22 09:42:31 檢舉

謝謝分享

我要發表回答

立即登入回答