如何将Python调用超市搜索API的代码转为浏览器端Ajax实现?
Question
I've used Python's
requestslibrary to call a supermarket's search API, which returns product names, prices, and unit pricing. Here's my working code:import requests import json payload ={ 'Filters':'[]', 'IsSpecial':'false', 'Location':'/shop/search/products?searchTerm=banana', 'PageNumber':'1', 'PageSize':'24', 'SearchTerm':'banana', 'SortType':'TraderRelevance' } url = "https://www.woolworths.com.au/apis/ui/Search/products" data = requests.post(url, json=payload).json() print(data['Products'][0]['Name']) print("$", data['Products'][0]['Products'][0]['Price'], "0", sep='') print(data['Products'][0]['Products'][0]['CupString']) print() print(data['Products'][1]['Name']) print("$", data['Products'][1]['Products'][0]['Price'], "0", sep='') print(data['Products'][1]['Products'][0]['CupString']) print() print(data['Products'][2]['Name']) print("$", data['Products'][0]['Products'][2]['Price'], "0", sep='') print(data['Products'][0]['Products'][2]['CupString']) print() ...I want to reuse this logic in a browser environment. Is this possible?
Answer
Great question! The short answer is yes, it's possible, but you'll need to navigate a critical browser security rule: the Same-Origin Policy. Here's what you need to know and how to implement it:
1. Why your direct browser request will fail
Browsers block requests from your frontend (e.g., a React/Vue app or plain HTML/JS) to https://www.woolworths.com.au if your frontend is hosted on a different domain (like localhost or your own website). This is the Same-Origin Policy, designed to prevent malicious cross-site requests.
2. Workarounds to fix the cross-origin issue
You have two main options to make this work:
Option A: Use a proxy server
- Development workaround: Use a browser extension (like CORS Unblock) to temporarily bypass the policy for testing. Note: This is only for local testing and not suitable for production.
- Production solution: Set up a simple proxy server (you can reuse your Python logic for this!) that acts as a middleman. Your frontend sends a request to your proxy, which then calls the Woolworths API and returns the data. Since the proxy is on the same origin as your frontend, the browser won't block it.
Option B: Backend request forwarding (best for production)
If you have an existing backend, modify it to handle the API call (just like your Python code does) and expose an endpoint for your frontend to call. For example, your frontend sends a GET/POST request to https://your-domain.com/api/search-products?term=banana, and your backend runs the requests code you already have, then sends the filtered product data back.
3. Example browser-side code (with proxy)
Once you have a proxy set up (or are using a testing workaround), here's how you can replicate your Python logic using the browser's native fetch API:
const payload = { 'Filters': '[]', 'IsSpecial': 'false', 'Location': '/shop/search/products?searchTerm=banana', 'PageNumber': '1', 'PageSize': '24', 'SearchTerm': 'banana', 'SortType': 'TraderRelevance' }; // Replace with your proxy URL or the Woolworths URL (if CORS is bypassed) const url = "https://your-proxy-domain.com/apis/ui/Search/products"; fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload) }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { // Loop through products and log/display them data.Products.forEach((productGroup) => { // Fixed the indexing typo from your original Python code const product = productGroup.Products[0]; console.log(productGroup.Name); console.log(`$${product.Price}0`); console.log(product.CupString); console.log(); }); }) .catch(error => { console.error('There was a problem with the fetch operation:', error); });
Key notes
- API Terms of Service: Make sure you're complying with Woolworths' API terms of service—scraping or using their API without permission might violate their policies.
- Error handling: Add proper error handling for network failures, invalid responses, or missing data fields (unlike your Python code, which assumes the data structure is always valid).
- Typo fix: In your original Python code, the third product accesses
data['Products'][0]['Products'][2]instead ofdata['Products'][2]['Products'][0]—the JavaScript example uses correct indexing to avoid errors.
内容的提问来源于stack exchange,提问作者The Fancyman

