2016-01-06 18 views
10

Tôi đang viết một trình bao bọc xung quanh fetch mà tôi muốn thêm nội dung nào đó vào URL trước khi thực hiện yêu cầu, ví dụ: xác định tham số truy vấn. Tôi không thể tìm ra cách tạo bản sao của đối tượng Request đã cho có URL khác với URL gốc. Mã của tôi trông giống như:Làm cách nào để sao chép đối tượng Yêu cầu bằng một URL khác?

// My function which tries to modify the URL of the request 
function addLangParameter(request) { 
    const newUrl = request.url + "?lang=" + lang; 
    return new Request(newUrl, /* not sure what to put here */); 
} 

// My fetch wrapper 
function myFetch(input, init) { 
    // Normalize the input into a Request object 
    return Promise.resolve(new Request(input, init)) 
     // Call my modifier function 
     .then(addLangParameter) 
     // Make the actual request 
     .then(request => fetch(request)); 
} 

tôi đã cố gắng đưa các yêu cầu ban đầu là arguent thứ hai để các nhà xây dựng Request, như vậy:

function addLangParameter(request) { 
    const newUrl = request.url + "?lang=" + lang; 
    return new Request(newUrl, request); 
} 

mà dường như để sao chép hầu hết các thuộc tính của các yêu cầu cũ nhưng dường như không giữ nguyên số body của yêu cầu cũ. Ví dụ:

const request1 = new Request("/", { method: "POST", body: "test" }); 
const request2 = new Request("/new", request1); 
request2.text().then(body => console.log(body)); 

Tôi muốn ghi lại "kiểm tra", nhưng thay vào đó, nó ghi lại chuỗi trống, vì nội dung không được sao chép.

Tôi có cần phải làm điều gì đó rõ ràng hơn để sao chép tất cả các thuộc tính một cách chính xác hay không hoặc có lối tắt đẹp nào sẽ làm điều gì đó hợp lý cho tôi không?

Tôi đang sử dụng vùng chèn github/fetch nhưng đã thử nghiệm với cả polyfill và triển khai thực hiện fetch gốc trong Chrome mới nhất.

+0

Không hiển thị mã giả: hiển thị mã thực. –

+0

@ Mike'Pomax'Kamermans Tôi đã thêm mã thực. Tôi nghĩ rằng nó làm cho nó khó khăn hơn để hiểu được vấn đề thực tế, có lẽ nó sẽ hữu ích. – Xymostech

+0

chứ không phải là khó khăn hơn, mã mới của bạn thực sự làm cho nó rõ ràng những gì bạn đang yêu cầu, bằng cách hiển thị của bạn sử dụng các đối tượng yêu cầu trong chính mã. –

Trả lời

7

Dường như đặt cược tốt nhất của bạn là để đọc nội dung bằng cách sử dụng giao diện Body rằng yêu cầu thực hiện:

https://fetch.spec.whatwg.org/#body

này chỉ có thể được thực hiện không đồng bộ từ cơ bản "tiêu thụ cơ thể" vận hành luôn luôn đọc không đồng bộ và trả lời một lời hứa. Một cái gì đó như thế này sẽ hoạt động:

const request = new Request('/old', { method: 'GET' }); 
const bodyP = request.headers.get('Content-Type') ? request.blob() : Promise.resolve(undefined); 
const newRequestP = 
    bodyP.then((body) => 
    new Request('/new', { 
     method: request.method, 
     headers: request.headers, 
     body: body, 
     referrer: request.referrer, 
     referrerPolicy: request.referrerPolicy, 
     mode: request.mode, 
     credentials: request.credentials, 
     cache: request.cache, 
     redirect: request.redirect, 
     integrity: request.integrity, 
    }) 
); 

Sau khi làm điều đó, newRequestP sẽ là lời hứa giải quyết yêu cầu bạn muốn. May mắn thay, lấy là không đồng bộ anyway để wrapper của bạn không nên bị cản trở đáng kể bởi điều này.

(Lưu ý: Đọc nội dung bằng cách sử dụng .blob() tắt yêu cầu không có nội dung có vẻ trả về đối tượng Blob có độ dài bằng không, nhưng không chính xác để xác định bất kỳ phần nào hoặc yêu cầu HEAD. Tôi tin rằng việc kiểm tra xem yêu cầu ban đầu có Content-Type là một proxy chính xác cho dù nó có cơ thể hay không, đó là những gì chúng tôi thực sự cần xác định.)

+2

Có vẻ như điều này hiện không hoạt động trong github/fetch polyfill (không đặt tiêu đề 'Content-Type' một cách thích hợp), nhưng nó hoạt động tốt trong Chrome. Cảm ơn! – Xymostech

+0

Một số thông tin tốt: https://github.com/whatwg/fetch/issues/191 – Endless

Các vấn đề liên quan