Rails 使用 JavaScript 原生的 fetch 很簡單

紅寶鐵軌客
Join to follow...
Follow/Unfollow Writer: 紅寶鐵軌客
By following, you’ll receive notifications when this author publishes new articles.
Don't wait! Sign up to follow this writer.
WriterShelf is a privacy-oriented writing platform. Unleash the power of your voice. It's free!
Sign up. Join WriterShelf now! Already a member. Login to WriterShelf.
寫程式中、折磨中、享受中 ......
894   0  
·
2020/03/14
·
3 mins read


我以前都很習慣用 JQuery 的 AJAX,但是最近我發現 JavaScript 原生的 fetch 也很好用,搭配上 json,使用起來也很方便,至於,何時會用 AJAX,何時用 fetch,這是我的建議:

  • 用 AJAX:當沒有 params 要傳,用 get 的時候,就用 AJAX 吧,呼叫簡單,
  • 用 fetch:有很多 params 要傳,用 post 的的時候,就用 fetch 加 json,好寫又清楚易懂。

以下就是 Rails 使用 fetch 的三步驟。

第一步,先來寫 javascript 部份:
// JS fetch: javascript 部份

// 檢查這網頁需不需要 load 這個 javascript,注意:這是沒有 turbolinks 時的寫法
$(document).ready( function() {
  if ($('#JS-id-this-page').length > 0) {
    // 下面的碼是有 monitor 一個 text_field 的 input event 示範,沒特別用意,可以改成別的,或是刪除,就是一個參考
    $('#JS-id-x-dom').on('input',function(event) {
      var value = event.target.value
      theFetch(value); // 所以當 #JS-id-x-dom 有輸入變化時,這個 function 就會執行。
    });
  };
});

function theFetch(value) {

  return fetch('/your_controller/your_action', { // 你要呼叫的 url
    // 以下通常都不需要寫,只是個參考
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, same-origin, *omit
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    },
    mode: 'cors', // no-cors, cors, *same-origin
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // *client, no-referrer
    // 這才是主要的部分
    method: 'post', //
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify({
      name: value
    })
  }).then(function(response) {
    // 你可以用 response.ok 來判斷是不是 4xx, 5xx  回覆,就看你需要不需要,
    // your_action 只會傳回成功,所以就沒寫這段
    // 注意:4xx, 5xx 不是網路錯誤,不會走下面 catch error,
    // 要 parsing json, 也就是說,我們的 Rails action 的回覆必須是 json
    return response.json();
  }).then(function(jsonData) {
    // jsonData 就是我們傳回來的資料了,看你要怎麼用都行,以下是一個簡單的判斷
    if (jsonData.action === true) {
      //console.log(jsonData.msg);
    } else {
      //console.log(jsonData.msg);
    }
  }).catch(function(error){
    // 網路錯誤
    // 注意:當 response 不是 :ok 時,是不會到這裡的,
    // 會到這裡都是網路錯誤,如:沒連網,網址錯誤
    //console.log('Error:', error);
  });

}

 

第二步,當然就是來寫 Rails 的部份了:

以下的碼就是要放在 your_controller 中:

# 下面這行是要放在 controller 的 before_action 那裡
skip_before_action :verify_authenticity_token, only: [:your_action]

def your_action

  v_name = params[:name]
  v_check_result = ""
  v_success = nil

  if v_name.length < 3 then
    v_check_result = "too short"
    v_success = false
  else
    v_check_result = "good"
    v_success = true
  end

  render json: { action: v_success, msg: v_check_result }, status: :ok
end

這個程式只做了一個很簡單的事,就是檢查字串長度,結果就放在 json 中傳回。

第一行是關閉 CSRF 保護,照理說要自己再寫 forgery protection,只是⋯⋯ 如果⋯⋯  好像不是很重要的資料時,大家就都算了。

第三步, 加入 route:
resources :your_controller do
  collection do
    post 'your_action'
  end
end
 
結束,就這樣

所以夠簡單吧,fetch 的速度比上 JQuery AJAX 一般都會是兩倍以上,不過兩者都很快啦,效率一般都不是考慮的主要因素,就如同文章一開頭,我是如果要做沒有 params 的 get 動作時,我就會用 JQuery AJAX,但是看各位的喜好啦,就算要用 fetch 來做有 params 的 get  動作也很容易,就是把 params 加在 url 內,用 JQuery 很容易做到的:

var url = "http://www.abc.com?" + $.param({foo: "bar", baz: "boon"})

 fetch 跟著 ES6 出現很久了,幾乎沒有瀏覽器不支援了,我想,我應該會越來越常用它,畢竟跟 JQuery 比,都一樣簡單好用,這時,好像沒有理由要用 JQuery 了。

 

 


WriterShelf™ is a unique multiple pen name blogging and forum platform. Protect relationships and your privacy. Take your writing in new directions. ** Join WriterShelf**
WriterShelf™ is an open writing platform. The views, information and opinions in this article are those of the author.


Article info

This article is part of:
Categories:
Tags:
Total: 846 words


Share this article:
About the Author

很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯




Join the discussion now!
Don't wait! Sign up to join the discussion.
WriterShelf is a privacy-oriented writing platform. Unleash the power of your voice. It's free!
Sign up. Join WriterShelf now! Already a member. Login to WriterShelf.