首页 > 解决方案 > Google App Script中的API Post请求不起作用

问题描述

我设法通过 Postman 完成 API POST 请求,但是一旦针对 Google App Script 进行了修改,它就不起作用了。我认为这可能与body格式有关,我无法new URLSearchParams()在 GAS 中复制对象(我相信我正在发送 JSON)。

谢谢。

邮递员(工作) - JavaScript Fetch

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "XXXX");
urlencoded.append("client_secret", "XXXX");
urlencoded.append("grant_type", "client_credentials");

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: urlencoded,
  redirect: 'follow'
};

fetch("https://apigateway.criteo.com/oauth2/token", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

卷曲

curl --location --request POST 'https://apigateway.criteo.com/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=XXXX' \
--data-urlencode 'client_secret=XXXX' \
--data-urlencode 'grant_type=client_credentials'

我的错误 GAS 版本 :(

function getCostAU() {
  
  var myHeaders = {"Accept": "application/json",
                   "Content-Type": "application/x-www-form-urlencoded"};
  
  var myPayload = {"client_id" : "XXXX",
                   "client_secret" : "XXXX",
                   "grant_type" : "client_credentials"};
  
  var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: myPayload,
    redirect: 'follow',
  };
    
  var url = "https://apigateway.criteo.com/oauth2/token";
  var result = JSON.parse(UrlFetchApp.fetch(url, requestOptions).getContentText());
  var access_token = result.access_token;
};

标签: javascriptgoogle-apps-scriptpostman

解决方案


问题:

解决方案:

  • 更改bodypayload

  • 将对象重新创建payload为查询字符串。例如,payload:{x:1,y:2}应更改为x=1&y=2.

片段:

  • 有效载荷对象查询参数:

function objectToQueryParams(obj) {
  return (
    Object.entries(obj)
      .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
      .join('&')
  );
}

const myPayload = {"client_id" : "XXXX",
               "client_secret" : "XXXX",
               "grant_type" : "client_credentials"};
  
console.log(objectToQueryParams(myPayload));

  • 有效requestOption
  const requestOptions = {
    /**@see https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)*/
    method: 'POST',
    headers: myHeaders,
    payload: objectToQueryParams(myPayload),//modified
    //or just payload: myPayload will work as mentioned in the comments below
    //redirect: 'follow',//removed 
    followRedirects: true
  };
  • 完整脚本:

/**Mock UrlFetchApp library*/
const UrlFetchApp = {
  fetch: () => ({
    getContentText: () =>
      '{"access_token":"jghlfdjlfwqwXjogsfshbkgetrwuguerjyrcyfxuux=="}',
  }),
};
getCostAU(); //call function
//Mock end


function getCostAU() {
  const myHeaders = {
    Accept: 'application/json',
    'Content-Type': 'application/x-www-form-urlencoded',
  };

  const myPayload = {
    client_id: 'XXXX',
    client_secret: 'XXXX',
    grant_type: 'client_credentials',
  };

  function objectToQueryParams(obj) {
    return Object.entries(obj)
      .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
      .join('&');
  }

  const requestOptions = {
    /**@see https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)*/
    method: 'POST',
    headers: myHeaders,
    payload: objectToQueryParams(myPayload), //modified
    //or just payload: myPayload will work as mentioned in the comments below
    //redirect: 'follow',//removed
    followRedirects: true,
  };

  const url = 'https://apigateway.criteo.com/oauth2/token';
  const result = JSON.parse(
    UrlFetchApp.fetch(url, requestOptions).getContentText()
  );
  const access_token = result.access_token;
  console.log(access_token);
}


推荐阅读