使用XHR发起异步请求调用Unplash与纽约时报API实现搜索功能的问题
Fixing Your Async Search Feature with Unsplash and NYT APIs
Hey there! I notice your code has the foundational structure for the search functionality, but there are a couple key missing pieces that are keeping it from working as expected. Let's walk through the fixes and get your feature up and running.
First off, your addArticles() and addImage() functions were empty—so even if the API requests succeeded, there was no code to display the results. Plus, you forgot to capture the search text from the input field, which meant your API calls were using an undefined value. Let's fix all that:
Here's the updated, working code:
(function(){ const form = document.querySelector('#search-form'); const searchField = document.querySelector('#search-keyword'); let searchedForText; const responseContainer = document.querySelector('#response-container'); // Helper to handle request errors gracefully function requestError(err, content type) { console.error(`Failed to load ${content type}:`, err); responseContainer.innerHTML += `<p class="error">Oops! There was an issue fetching ${content type}.</p>`; } // Render Unsplash image results function addImage() { const data = JSON.parse(this.responseText); if (data.results.length) { const topImage = data.results[0]; responseContainer.innerHTML += ` <figure> <img src="${topImage.urls.regular}" alt="${searchedForText}"> <figcaption>Photo by ${topImage.user.name} on Unsplash</figcaption> </figure> `; } else { responseContainer.innerHTML += `<p>No images found for "${searchedForText}".</p>`; } } // Render NYT article results function addArticles() { const data = JSON.parse(this.responseText); if (data.response.docs.length) { let articleList = '<ul class="articles">'; data.response.docs.forEach(article => { const headline = article.headline.main || 'No Headline'; const snippet = article.snippet || 'No preview available'; articleList += ` <li> <h3><a href="${article.web_url}" target="_blank">${headline}</a></h3> <p>${snippet}</p> </li> `; }); articleList += '</ul>'; responseContainer.innerHTML += articleList; } else { responseContainer.innerHTML += `<p>No articles found for "${searchedForText}".</p>`; } } form.addEventListener('submit', function(e) { e.preventDefault(); responseContainer.innerHTML = ''; searchedForText = searchField.value.trim(); // Capture the user's search input! // Guard clause for empty search if (!searchedForText) { responseContainer.innerHTML += '<p>Please enter a search term first.</p>'; return; } // Unsplash API request const imgRequest = new XMLHttpRequest(); imgRequest.onload = addImage; imgRequest.onerror = err => requestError(err, 'images'); imgRequest.open('GET', `https://api.unsplash.com/search/photos?page=1&query=${encodeURIComponent(searchedForText)}`); imgRequest.setRequestHeader('Authorization', 'Client-ID YOUR_UNSPLASH_CLIENT_ID'); // Replace with your key imgRequest.send(); // NYT API request const articleRequest = new XMLHttpRequest(); articleRequest.onload = addArticles; articleRequest.onerror = err => requestError(err, 'articles'); articleRequest.open('GET', `https://api.nytimes.com/svc/search/v2/articlesearch.json?q=${encodeURIComponent(searchedForText)}&api-key=YOUR_NYT_API_KEY`); // Replace with your key articleRequest.send(); }); })();
Key Improvements & Fixes:
- Captured search input: Added
searchedForText = searchField.value.trim()to grab what the user typed (this was missing in your original code!) - Filled result rendering functions:
addImage()andaddArticles()now parse API responses and display content properly, including handling empty result cases. - Safe search term encoding: Used
encodeURIComponent()to handle spaces/special characters in search queries. - Error handling: Added user-friendly error messages and console logs for debugging.
- Cleaned up API key placeholders: Reminded you to replace the placeholder keys with your actual valid keys from the Unsplash and NYT developer portals.
Quick Reminders:
- Ensure your HTML includes the required elements:
<form id="search-form">,<input id="search-keyword">, and<div id="response-container">. - Keep your API keys secure—don't share them publicly in production (Codepen is fine for testing, but use a backend proxy in real apps).
Content of the question originates from Stack Exchange, asked by Oksana Shukh
相关产品推荐
相关产品推荐

