4.6 בקשות HTTP פתרון
פתרון - בקשות HTTP¶
פתרון תרגיל 1¶
async function getUser(id) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
if (!response.ok) {
throw new Error(`User not found (status ${response.status})`);
}
const user = await response.json();
console.log(`${user.name} - ${user.email}`);
return user;
} catch (error) {
console.error("Error:", error.message);
}
}
await getUser(1); // "Leanne Graham - Sincere@april.biz"
await getUser(999); // "Error: User not found (status 404)"
פתרון תרגיל 2¶
async function displayPosts() {
const container = document.getElementById("posts");
container.textContent = "Loading...";
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const posts = await response.json();
container.textContent = ""; // clear loading message
posts.forEach(post => {
const card = document.createElement("div");
card.className = "post-card";
card.innerHTML = `
<h3>${post.title}</h3>
<p>${post.body}</p>
`;
container.appendChild(card);
});
} catch (error) {
container.textContent = `Error: ${error.message}`;
}
}
displayPosts();
פתרון תרגיל 3¶
<form id="postForm">
<input type="text" id="title" placeholder="Title" required>
<textarea id="body" placeholder="Content" required></textarea>
<button type="submit">Create Post</button>
</form>
<div id="result"></div>
async function createPost(postData) {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(postData)
});
if (!response.ok) {
throw new Error(`Failed to create post (status ${response.status})`);
}
const created = await response.json();
console.log("Created:", created);
return created;
} catch (error) {
console.error("Error:", error.message);
}
}
document.getElementById("postForm").addEventListener("submit", async (e) => {
e.preventDefault();
const title = document.getElementById("title").value;
const body = document.getElementById("body").value;
const result = await createPost({ title, body, userId: 1 });
if (result) {
document.getElementById("result").textContent =
`Post created with id: ${result.id}`;
}
});
פתרון תרגיל 4¶
async function searchPosts(userId, limit) {
try {
const params = new URLSearchParams({ userId });
if (limit) {
params.append("_limit", limit);
}
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?${params}`
);
if (!response.ok) {
throw new Error(`Search failed (status ${response.status})`);
}
const posts = await response.json();
console.log(`Found ${posts.length} posts by user ${userId}:`);
posts.forEach(post => {
console.log(` - ${post.title}`);
});
return posts;
} catch (error) {
console.error("Error:", error.message);
}
}
await searchPosts(1); // all posts by user 1
await searchPosts(1, 3); // first 3 posts by user 1
פתרון תרגיל 5¶
const BASE_URL = "https://jsonplaceholder.typicode.com";
const PostService = {
async getAll() {
try {
const response = await fetch(`${BASE_URL}/posts`);
if (!response.ok) {
throw new Error(`Failed to get posts (${response.status})`);
}
return await response.json();
} catch (error) {
console.error("getAll error:", error.message);
throw error;
}
},
async getById(id) {
try {
const response = await fetch(`${BASE_URL}/posts/${id}`);
if (!response.ok) {
throw new Error(`Post ${id} not found (${response.status})`);
}
return await response.json();
} catch (error) {
console.error("getById error:", error.message);
throw error;
}
},
async create(data) {
try {
const response = await fetch(`${BASE_URL}/posts`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`Failed to create post (${response.status})`);
}
return await response.json();
} catch (error) {
console.error("create error:", error.message);
throw error;
}
},
async update(id, data) {
try {
const response = await fetch(`${BASE_URL}/posts/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`Failed to update post ${id} (${response.status})`);
}
return await response.json();
} catch (error) {
console.error("update error:", error.message);
throw error;
}
},
async delete(id) {
try {
const response = await fetch(`${BASE_URL}/posts/${id}`, {
method: "DELETE"
});
if (!response.ok) {
throw new Error(`Failed to delete post ${id} (${response.status})`);
}
console.log(`Post ${id} deleted`);
} catch (error) {
console.error("delete error:", error.message);
throw error;
}
}
};
// testing
const posts = await PostService.getAll();
console.log(posts.length); // 100
const post = await PostService.getById(1);
console.log(post.title);
const newPost = await PostService.create({ title: "Test", body: "Body", userId: 1 });
console.log(newPost.id); // 101
await PostService.update(1, { title: "Updated", body: "New body", userId: 1 });
await PostService.delete(1);
פתרון תרגיל 6¶
א. fetchWithTimeout:
async function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
throw new Error(`Request timed out after ${timeout}ms`);
}
throw error;
}
}
// testing
try {
const response = await fetchWithTimeout(
"https://jsonplaceholder.typicode.com/posts",
{},
3000
);
const data = await response.json();
console.log(`Got ${data.length} posts`);
} catch (error) {
console.error(error.message);
}
ב. fetchLatest:
let currentController = null;
async function fetchLatest(endpoint) {
// cancel previous request if it exists
if (currentController) {
currentController.abort();
}
currentController = new AbortController();
const myController = currentController; // save reference
try {
const response = await fetch(
`https://jsonplaceholder.typicode.com${endpoint}`,
{ signal: myController.signal }
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
console.log("Got result for:", endpoint);
return data;
} catch (error) {
if (error.name === "AbortError") {
console.log("Cancelled:", endpoint);
return null;
}
throw error;
}
}
פתרון תרגיל 7¶
async function getUserWithPosts(userId) {
try {
const [userResponse, postsResponse] = await Promise.all([
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`),
fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`)
]);
if (!userResponse.ok) {
throw new Error(`User not found (${userResponse.status})`);
}
if (!postsResponse.ok) {
throw new Error(`Failed to get posts (${postsResponse.status})`);
}
const [user, posts] = await Promise.all([
userResponse.json(),
postsResponse.json()
]);
return { user, posts };
} catch (error) {
console.error("Error:", error.message);
throw error;
}
}
const result = await getUserWithPosts(1);
console.log(result.user.name); // "Leanne Graham"
console.log(result.posts.length); // 10
פתרון תרגיל 8¶
function createApiClient(baseUrl) {
let authToken = null;
async function request(endpoint, options = {}) {
const { method = "GET", body, timeout = 10000 } = options;
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json"
};
if (authToken) {
headers["Authorization"] = `Bearer ${authToken}`;
}
const config = {
method,
headers,
signal: controller.signal
};
if (body) {
config.body = JSON.stringify(body);
}
try {
const response = await fetch(`${baseUrl}${endpoint}`, config);
clearTimeout(timeoutId);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
const error = new Error(errorData.message || `HTTP ${response.status}`);
error.status = response.status;
throw error;
}
if (response.status === 204) {
return null;
}
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
throw new Error("Request timed out");
}
throw error;
}
}
return {
setToken(token) {
authToken = token;
},
get(endpoint) {
return request(endpoint);
},
post(endpoint, body) {
return request(endpoint, { method: "POST", body });
},
put(endpoint, body) {
return request(endpoint, { method: "PUT", body });
},
delete(endpoint) {
return request(endpoint, { method: "DELETE" });
}
};
}
// testing
const client = createApiClient("https://jsonplaceholder.typicode.com");
client.setToken("my-secret-token");
const posts = await client.get("/posts");
console.log(posts.length); // 100
const newPost = await client.post("/posts", { title: "Hi", body: "World", userId: 1 });
console.log(newPost.id); // 101
await client.put("/posts/1", { title: "Updated", body: "New", userId: 1 });
await client.delete("/posts/1");