对同一 URL 的第二次 AJAX 调用失败 - 但随机且很少工作
Posted
技术标签:
【中文标题】对同一 URL 的第二次 AJAX 调用失败 - 但随机且很少工作【英文标题】:2nd AJAX call to same URL fails - but works randomly and rarely 【发布时间】:2018-05-24 10:04:47 【问题描述】:我正在尝试从 Web 服务获取响应,特别是将两个 WFS 图层从地理服务器添加到传单 Web 地图。每次加第一层都没问题,但大多数时候第二层失败,抱怨没有定义回调函数:
ReferenceError: getJson is not defined
但我很奇怪的是,第二层会被添加,只是有时。刷新页面并重试几乎总是会失败。
这是进行 ajax 调用的代码:
$(document).ready(function()
...
$("#add-network-button").on("click", function() setLocation("Moscow"))
function setLocation(locationName)
var networkParameters =
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'netex:' + locationData[locationName].networkWFSName,
maxFeatures: 99999,
outputFormat: 'text/javascript',
format_options: 'callback: getJson'
;
addWebService(map, WFSURL, networkParameters)
var buildingParameters =
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'netex:' + locationData[locationName].buildingWFSName,
maxFeatures: 99999,
outputFormat: 'text/javascript',
format_options: 'callback: getJson'
;
addWebService(map, WFSURL, buildingParameters)
这里是addWebService
函数:
var addWebService = function(map, WFSURL, WFSParameters)
var leafletWFSParameters = L.Util.extend(WFSParameters);
console.log(WFSURL + L.Util.getParamString(leafletWFSParameters));
$.ajax(
url: WFSURL + L.Util.getParamString(leafletWFSParameters),
dataType: 'jsonp',
jsonpCallback: 'getJson',
success: handleJson,
cache: false
);
// TODO: add style
function handleJson(data)
L.geoJson(data, ).addTo(map);
【问题讨论】:
小更新:设置 ajax 调用参数async: false
似乎已经解决了这个问题,但我从那些比我更有经验的人那里听说这不是一个“正确”的解决方案,但我不是真的很清楚为什么。
【参考方案1】:
您正在使用jsonp
,这意味着您返回的数据不是 JSON,而是调用全局定义函数(名称由 jsonpCallback
定义)的 javascript 代码。
jQuery 自动创建一个具有该名称的函数,执行网络请求,并且当该函数运行时,它会从全局范围内销毁它自己的引用。
您正在快速连续执行两次对addWebService()
的调用,这会触发两次jQuery $.ajax(jsonpCallback: 'getJson')
调用。第二个调用是覆盖全局定义的getJson
回调函数。当您的浏览器接收到第一个 jsonp 有效负载时,全局定义的 getJson
回调将被销毁。当接收到第二个 jsonp 有效负载时,它会尝试调用全局定义的 getJson
函数,但失败了。经典的比赛条件。
让我引用jQuery's documentation for the jsonpCallback
parameter on $.ajax()
,强调我的:
jsonp回调
类型:字符串或函数()
为 JSONP 请求指定回调函数名称。 将使用此值代替随机名称 由 jQuery 自动生成。 最好让 jQuery 生成一个唯一的名称,因为这样可以更轻松地管理 请求并提供回调和错误处理。你可能想要 当您想要启用更好的浏览器缓存时指定回调 GET 请求。
我建议您要么使用 JSONP 以外的其他传输格式,要么为每个请求使用不同的回调名称。
【讨论】:
如果我跳过参数(因此让它取一个随机名称),它会失败,因为它仍在寻找getJson
。我在想这可能是geoserver本身的一个限制,它需要函数有这个名字。
是的,但那是因为您在代码的其他部分将 format_options: 'callback: getJson'
传递给 geoserver。以上是关于对同一 URL 的第二次 AJAX 调用失败 - 但随机且很少工作的主要内容,如果未能解决你的问题,请参考以下文章
Asp .Net Core WebApi:异常的第二次http调用
我的 CustomDeserializer 类在同一类的第二个字段上第二次不起作用