如何用JavaScript异步获取指定坐标附近的地标设施?
Hey there, let's break this down into the core issues you're facing and fix them one by one—you've been stuck long enough!
为什么会遇到跨域+解析错误?
Google Places API doesn't allow direct frontend cross-origin requests (it doesn't send the Access-Control-Allow-Origin header), so your browser blocks the response. And that "parse error" you're seeing? It's probably because you're trying to parse a JSONP response as regular JSON, or the request format doesn't match what Google expects.
方案1:使用Google Places JavaScript SDK(官方推荐,无跨域)
This is the simplest fix—Google built a frontend library specifically for this, so no more CORS headaches. Plus it's optimized for performance.
- Step 1: Load the SDK (replace
YOUR_API_KEYwith your actual key):
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
- Step 2: Search for multiple facility types efficiently
You can batch requests for hospitals, schools, stores instead of looping synchronously. Here's a quick example:
// Create a hidden map container (required for the PlacesService to work) const map = new google.maps.Map(document.getElementById('hidden-map'), { center: { lat: YOUR_TARGET_LAT, lng: YOUR_TARGET_LNG }, zoom: 15 }); const placesService = new google.maps.places.PlacesService(map); // Define the facility types you want to search for const facilityTypes = ['hospital', 'school', 'store']; // Batch search requests facilityTypes.forEach(type => { placesService.nearbySearch({ location: { lat: YOUR_TARGET_LAT, lng: YOUR_TARGET_LNG }, radius: 5000, // Adjust radius (in meters) as needed type: type }, (results, status) => { if (status === google.maps.places.PlacesServiceStatus.OK) { // Handle results for this type—render them, store in an array, etc. console.log(`${type} results:`, results); } else { console.error(`Failed to fetch ${type}s:`, status); } }); });
- Why this works: The SDK handles all the cross-origin logic internally, and Google's infrastructure makes these requests faster than rolling your own.
方案2:PHP Backend Proxy (Reuse Your Existing Code + Fix Slow Loads)
If you prefer sticking with PHP, turn your backend into a proxy to call Google's API (server-to-server requests don't have CORS limits). Plus, we'll fix that 7-second load time by making parallel requests instead of looping synchronously.
Optimize PHP: Serial → Parallel Requests
Instead of waiting for each API call to finish before starting the next, use Guzzle to send requests at the same time:
require 'vendor/autoload.php'; // Load Guzzle use GuzzleHttp\Client; use GuzzleHttp\Promise; $client = new Client(); $apiKey = 'YOUR_API_KEY'; $lat = YOUR_TARGET_LAT; $lng = YOUR_TARGET_LNG; $radius = 5000; // List of facility types to search $types = ['hospital', 'school', 'store']; $promises = []; // Create async requests for each type foreach ($types as $type) { $url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location={$lat},{$lng}&radius={$radius}&type={$type}&key={$apiKey}"; $promises[$type] = $client->getAsync($url); } // Wait for all requests to complete $responses = Promise\unwrap($promises); // Process and combine results $finalResults = []; foreach ($responses as $type => $response) { $data = json_decode($response->getBody(), true); $finalResults[$type] = $data['status'] === 'OK' ? $data['results'] : ['error' => $data['status']]; } // Send combined JSON to frontend header('Content-Type: application/json'); echo json_encode($finalResults);
Then your frontend only needs one Ajax call to your PHP proxy:
$.ajax({ url: 'your-proxy-script.php', method: 'GET', data: { lat: YOUR_TARGET_LAT, lng: YOUR_TARGET_LNG }, success: function(allResults) { // Handle all facility types at once console.log('All facilities:', allResults); }, error: function(xhr, status, err) { console.error('Proxy error:', err); } });
- Performance win: Parallel requests will cut that 7-second load time down to 1-2 seconds, since you're not waiting for each call sequentially.
Fixing the Parse Error (If You Insist on Frontend Direct Calls)
If you really want to skip the proxy/SDK, you need to use JSONP instead of regular JSON, because Google returns JSONP for frontend requests:
$.ajax({ url: 'https://maps.googleapis.com/maps/api/place/nearbysearch/json', method: 'GET', data: { location: `${YOUR_TARGET_LAT},${YOUR_TARGET_LNG}`, radius: 5000, type: 'hospital', key: 'YOUR_API_KEY' }, dataType: 'jsonp', // Critical: tells jQuery to handle JSONP success: function(data) { console.log('Results:', data); } });
But honestly, this is not recommended—JSONP has security risks, and the SDK/proxy methods are way more reliable.
Final Recap
- CORS Fix: Use the official JS SDK or a PHP proxy (server-to-server requests avoid CORS).
- Performance Fix: Replace serial PHP loops with parallel async requests (Guzzle promises).
- Parse Error Fix: Match your request format to Google's response (use JSONP if going direct, or let the SDK/proxy handle parsing).
This should get you up and running in no time!
内容的提问来源于stack exchange,提问作者Purushotam Sangroula

