การตั้งค่าสตริงแบบสอบถามโดยใช้การดึงข้อมูลคำขอ GET


149

ฉันพยายามใช้API การดึงข้อมูลใหม่:

ฉันกำลังGETขอสิ่งนี้:

var request = new Request({
  url: 'http://myapi.com/orders',
  method: 'GET'
});
fetch(request);

อย่างไรก็ตามฉันไม่แน่ใจว่าจะเพิ่มสตริงข้อความค้นหาในGETคำขอได้อย่างไร เป็นการดีที่ฉันต้องการที่จะสามารถGETขอให้URLชอบ:

'http://myapi.com/orders?order_id=1'

ในjQueryที่ฉันสามารถทำเช่นนี้โดยการส่งผ่าน{order_id: 1}เป็นพารามิเตอร์ของdata $.ajax()มีวิธีที่เทียบเท่ากับการทำเช่นนั้นกับใหม่Fetch APIหรือไม่

คำตอบ:


174

อัปเดตมีนาคม 2560:

URL.searchParamsสนับสนุนมีที่ดินอย่างเป็นทางการใน Chrome 51 แต่เบราว์เซอร์อื่น ๆ ยังคงต้องมีการpolyfill


อย่างเป็นทางการทางที่จะทำงานร่วมกับพารามิเตอร์การค้นหาเป็นเพียงการเพิ่มพวกเขาไปยัง URL นั้น จากข้อมูลจำเพาะนี่เป็นตัวอย่าง:

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

แต่ผมไม่แน่ใจว่า Chrome สนับสนุนsearchParamsทรัพย์สินของ URL (ในขณะที่เขียน) ดังนั้นคุณอาจต้องการให้ทั้งใช้ห้องสมุดของบุคคลที่สามหรือวิธีการแก้ปัญหาม้วนของคุณเอง

อัปเดตเมษายน 2018:

ด้วยการใช้ตัวสร้าง URLSearchParamsคุณสามารถกำหนดอาร์เรย์ 2 มิติหรือวัตถุและเพียงกำหนดให้กับurl.searchแทนที่จะวนลูปมากกว่าปุ่มทั้งหมดและผนวกพวกเขา

var url = new URL('https://sl.se')

var params = {lat:35.696233, long:139.570431} // or:
var params = [['lat', '35.696233'], ['long', '139.570431']]

url.search = new URLSearchParams(params).toString();

fetch(url)

Sidenote: URLSearchParamsยังมีอยู่ใน NodeJS

const { URL, URLSearchParams } = require('url');

1
นอกจากนี้ยังมีdeveloper.mozilla.org/en-US/docs/Web/API/URLSearchParams/ ...... ผู้เขียนนี้ยังคงดำเนินการผ่านสเป็ค แต่ยังไม่ได้รับการสนับสนุน และ API ก็เหมือน Java มากกว่า JS : /
ericsoco

1
ดูcaniuse.com/#feat=urlsearchparamsเพื่อรับการสนับสนุนURLSearchParamsอินเทอร์เฟซ ฉันจะถือว่า (แม้ว่าฉันจะไม่แน่ใจ 100%) ว่าเบราว์เซอร์สีแดงมีเบราว์เซอร์ที่URLวัตถุจะไม่มี.searchParamsคุณสมบัติ ที่สำคัญ Edge ยังไม่รองรับ
Mark Amery

1
จากเอกสาร: "โปรดทราบว่าการใช้อินสแตนซ์ URLSearchParams จะถูกคัดค้านในไม่ช้าเบราว์เซอร์จะใช้ USVString สำหรับผู้เริ่มต้นเท่านั้น" แหล่งที่มา: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/ …
pakman

1
new URLSearchParamsดูเหมือนจะทำงานไม่ถูกต้องกับArrayคุณสมบัติ ผมคาดว่ามันจะแปลงทรัพย์สินarray: [1, 2]ไปแต่แปลงมันarray[]=1&array[]=2 array=1,2การใช้appendวิธีการด้วยตนเองจะส่งผลarray=1&array=2ให้ แต่ฉันจะต้องทำซ้ำมากกว่าวัตถุ params และทำอย่างนั้นเฉพาะสำหรับประเภทอาร์เรย์ไม่เหมาะกับการทำงานมาก
erandros

1
มันถูกเพิ่มเข้ามาในความผิดพลาดแน่นอน :) github.com/mdn/sprints/issues/2856
CodingIntrigue

30
let params = {
  "param1": "value1",
  "param2": "value2"
};

let query = Object.keys(params)
             .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
             .join('&');

let url = 'https://example.com/search?' + query;

fetch(url)
  .then(data => data.text())
  .then((text) => {
    console.log('request succeeded with JSON response', text)
  }).catch(function (error) {
    console.log('request failed', error)
  });

26

ตามที่ได้ตอบไปแล้วสิ่งนี้เป็นไปตามข้อกำหนดที่เป็นไปไม่ได้กับfetch-API แต่ฉันต้องทราบ:

ถ้าคุณอยู่nodeมีquerystringแพคเกจ มันสามารถทำให้สตริง / แยกวิเคราะห์วัตถุ / querystrings:

var querystring = require('querystring')
var data = { key: 'value' }
querystring.stringify(data) // => 'key=value'

... จากนั้นเพียงเพิ่มต่อท้าย URL เพื่อขอ


อย่างไรก็ตามปัญหาข้างต้นคือคุณต้องใส่เครื่องหมายคำถาม ( ?) เสมอ ดังนั้นอีกวิธีหนึ่งคือการใช้parseวิธีการจากurlแพคเกจโหนดและทำดังต่อไปนี้:

var url = require('url')
var data = { key: 'value' }
url.format({ query: data }) // => '?key=value'

ดูqueryที่https://nodejs.org/api/url.html#url_url_format_urlobj

นี้เป็นไปตามที่มันไม่ภายในเพียงแค่นี้ :

search = obj.search || (
    obj.query && ('?' + (
        typeof(obj.query) === 'object' ?
        querystring.stringify(obj.query) :
        String(obj.query)
    ))
) || ''

25

วิธีกระชับ ES6:

fetch('https://example.com?' + new URLSearchParams({
    foo: 'value',
    bar: 2,
}))

ฟังก์ชัน toString () ของ URLSearchParamsจะแปลงข้อความค้นหาเป็นสตริงที่สามารถต่อท้าย URL ได้ ในตัวอย่างนี้ toString () ถูกเรียกโดยปริยายเมื่อได้รับการต่อกับ URL

IE ไม่สนับสนุน URLSearchParams แต่มีpolyfillsใช้ได้

ถ้าใช้โหนดคุณสามารถหา URLSearchParams เป็นวัตถุทั่วโลกตั้งแต่รุ่น 10 ในรุ่นเก่าที่คุณสามารถค้นหาได้ที่require('url').URLSearchParamsแทน ที่เกิดขึ้นจริงสามารถดึงข้อมูล API ไม่เป็นส่วนหนึ่งของโหนดและความต้องการที่จะเพิ่มผ่านแพคเกจเช่นโหนดสามารถดึงข้อมูล



5

บางทีนี่อาจจะดีกว่า:

const withQuery = require('with-query');

fetch(withQuery('https://api.github.com/search/repositories', {
  q: 'query',
  sort: 'stars',
  order: 'asc',
}))
.then(res => res.json())
.then((json) => {
  console.info(json);
})
.catch((err) => {
  console.error(err);
});

5

encodeQueryString - เข้ารหัสวัตถุเป็นพารามิเตอร์การสืบค้น

/**
 * Encode an object as url query string parameters
 * - includes the leading "?" prefix
 * - example input — {key: "value", alpha: "beta"}
 * - example output — output "?key=value&alpha=beta"
 * - returns empty string when given an empty object
 */
function encodeQueryString(params) {
    const keys = Object.keys(params)
    return keys.length
        ? "?" + keys
            .map(key => encodeURIComponent(key)
                + "=" + encodeURIComponent(params[key]))
            .join("&")
        : ""
}

encodeQueryString({key: "value", alpha: "beta"})
 //> "?key=value&alpha=beta"

5

ฉันรู้ว่านี่เป็นการระบุชัดเจนแน่นอน แต่ฉันรู้สึกว่ามันคุ้มค่าที่จะเพิ่มคำตอบนี้เพราะมันง่ายที่สุดของทั้งหมด:

var orderId = 1;
var request = new Request({
  url: 'http://myapi.com/orders?order_id=' + orderId,
  method: 'GET'
});
fetch(request);

7
มันมีคุณสมบัติพอที่จะใช้กับประเภทจำนวนเต็มได้อย่างน่าเชื่อถือ หากคุณใช้สตริงโดยเฉพาะอย่างยิ่งจากผู้ใช้ (เช่นเกณฑ์การค้นหา) แล้วคุณจะต้องหลบหนีสตริงมิฉะนั้นคุณจะได้รับผลแปลกถ้าตัวละครที่ชอบ/, +หรือ&ปรากฏในสตริง
Malvineous

การใช้คำขอวัตถุสามารถช่วยได้โดยเฉพาะถ้าคุณต้องการใช้ฟังก์ชั่นในการสร้างคำขอจากนั้นส่งมอบให้กับการเรียก fetch () แต่ฉันไม่คิดว่าการใช้มันเป็น "ชัดเจนที่สุด" นอกจากนี้ไม่ควรระบุ URL ในวัตถุตามตัวเลือกการกำหนดค่า มันควรจะส่งผ่านแยกกันเป็นพารามิเตอร์ที่ 1 ให้กับตัวสร้างคำขอ ( developer.mozilla.org/en-US/docs/Web/API/Request/Request )
Gen1-1

3

เทมเพลตตัวอักษรเป็นตัวเลือกที่ถูกต้องที่นี่และให้ประโยชน์เล็กน้อย

คุณสามารถรวมสตริงดิบตัวเลขค่าบูลีนและอื่น ๆ :

    let request = new Request(`https://example.com/?name=${'Patrick'}&number=${1}`);

คุณสามารถรวมตัวแปร:

    let request = new Request(`https://example.com/?name=${nameParam}`);

คุณสามารถรวมตรรกะและฟังก์ชั่น:

    let request = new Request(`https://example.com/?name=${nameParam !== undefined ? nameParam : getDefaultName() }`);

เท่าที่โครงสร้างข้อมูลของสตริงแบบสอบถามที่มีขนาดใหญ่ขึ้นฉันชอบใช้อาร์เรย์ที่เชื่อมต่อกับสตริง ฉันเข้าใจว่าง่ายกว่าวิธีอื่น ๆ :

let queryString = [
  `param1=${getParam(1)}`,
  `param2=${getParam(2)}`,
  `param3=${getParam(3)}`,
].join('&');

let request = new Request(`https://example.com/?${queryString}`, {
  method: 'GET'
});

9
คุณจะต้องระมัดระวังอย่างมากกับวิธีนี้เพราะมันไม่ได้ URL หนีสตริงก่อน ดังนั้นหากคุณได้รับตัวแปรที่มีตัวละครที่ชอบ+หรือไม่เช่น&นั้นมันจะไม่ทำงานตามที่คาดไว้และคุณจะได้รับพารามิเตอร์และค่าต่าง ๆ ตามที่คุณคิด
Malvineous

-1

เคยทำงานกับ fetchModule ของ Nativescript และหาวิธีแก้ปัญหาของตัวเองโดยใช้การจัดการสตริง ผนวกคิวรีสตริงการค้นหาแบบทีละบิตไปยัง URL นี่คือตัวอย่างที่ส่งผ่านเคียวรีเป็นอ็อบเจ็กต์ json (query = {order_id: 1}):

function performGetHttpRequest(fetchLink='http://myapi.com/orders', query=null) {
    if(query) {
        fetchLink += '?';
        let count = 0;
        const queryLength = Object.keys(query).length;
        for(let key in query) {
            fetchLink += key+'='+query[key];
            fetchLink += (count < queryLength) ? '&' : '';
            count++;
        }
    }
    // link becomes: 'http://myapi.com/orders?order_id=1'
    // Then, use fetch as in MDN and simply pass this fetchLink as the url.
}

ฉันทดสอบสิ่งนี้กับพารามิเตอร์การสืบค้นจำนวนมากและทำงานได้อย่างมีเสน่ห์ :) หวังว่านี่จะช่วยให้ใครบางคน


1
นี่เป็นตัวอย่างที่ดีว่าทำไมคุณควรใช้ libs ของบุคคลที่สาม - รหัสของคุณอาจทำงานได้ดี แต่มีคนทำดีกว่าอยู่แล้ว
refaelio

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.