Unk*_*per 1 javascript json jsonp angularjs angular-promise
想象一下JSON(, instead of :)中的以下语法错误:
[
{
"name": "anna",
"email": "anna@gmail.com",
"town", "london"
},
...
]
Run Code Online (Sandbox Code Playgroud)
我想知道是否有可能处理此错误而不是获取异常,获取错误的对象,更正错误并继续使用正确的版本.
这是我的Angular服务的一部分; 我试图获取文本而不是JSON数据,但它不起作用......
angular.module('mine', [])
.config(function($sceProvider) {
// Completely disable SCE.
$sceProvider.enabled(false);
})
.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'http://www.mocky.io/v2/5807df4a10000004122b74e2'
]);
}])
.config(function ($httpProvider) {
$httpProvider.interceptors.push(function($q) {
return {
'request': function(config) {
config.headers.Accept = 'text/plain';
return config;
},
'response': function(response) {
try {
// try to parse it
response.data = JSON.parse(response.data);
} catch (ex) {
// try to fix it
console.log("error " + ex);
console.log(response.data);
response.data = {fixed_data : "data"};
}
// return the corect data.
// note that the original response.data WILL BE CHANGED and this is expected.
return response;
}
};
});
})
angular.module('mine').factory('MyFactory', ['$http','$q', function MyFactory($http,$q) {
return {
getData: function() {
var deferred = $q.defer(),
config = {
params: { }
},
url="http://www.mocky.io/v2/5807df4a10000004122b74e2";
$http.jsonp(url,config)
.then(
function (response) {
deferred.resolve(response.data);
},
function (error) {
console.log(error);
return $q.reject('Error retrieving data');
}
);
return deferred.promise;
}
};
}]);
Run Code Online (Sandbox Code Playgroud)
无论如何将上述承诺引入成功回调,检索错误的JSON并进行纠正?我怎么可以根据上面的例子编写代码呢?
或者更容易一些,如何检索文本而不是JSON数据,$http.jsonp以免被驱动到失败回调?
在进一步了解OP问题后编辑:
在您想要编辑响应内容的一般情况下,您可以使用"拦截器"进行编辑,但响应应该是合法的.也就是说,如果你想在一个正确的JSON中将数字字符串更改为整数 - 那么这是可能的.
在这种情况下,OP在JSON格式不正确的情况下正在升级 - 这是不可能的!
进入经典的XY问题!
您应该问自己为什么JSON会被破坏而不会尝试在客户端代码中修复它.想一想 - 如果你现在修复它,你只会遇到更多的问题,后来有人会修复这个问题 - 那么你将会遇到破解的代码.
如果JSON应该是:
[
{
"name": "anna",
"email": "anna@gmail.com",
"addresses": [{"town": "london", ...}, ...]
},
...
]
Run Code Online (Sandbox Code Playgroud)
或者(上帝保佑):
[
{
"name": "anna",
"email": ["anna@gmail.com","town", "london"]
},
...
]
Run Code Online (Sandbox Code Playgroud)
你知道 - 我的观点是 - API被破坏了,它可以是任何东西.你应该修复API.如果此API不是您的修复 - >使用其他API或联系所有者来修复它.
JSONP是一种让API直接调用代码的方法.您必须信任此API.如果API会给我错误的JSON - 我会离开!
简而言之,JSONP在Angular中(或实际上在任何地方)的工作方式是通过将<script>标记注入到DOM中并src指向JSONp请求的URL.
服务器将使用函数名称填充 JSON数据(最常见callback但它可以是任何全局可访问的函数(Angular正在使用angular.callbacks._xyz)并将发送它.
然后浏览器调用从中下载的脚本src.
现在,问题在于它是调用脚本的浏览器.它不在Angular的手中.而这正是OP正面临的问题-脚本必须以正确的JavaScript进行评估,以开始与浏览器是这样做的,没有棱角.这是必须的.你无法进入它的中间.如果你这样做,可能会带来安全风险.这就是为什么,例如,JSONP请求的响应将始终(按照惯例...)返回MIME类型,application/javascript无论您要求什么.
我劝你不要走这条路!
如果你坚持要从JSONP调用一个带有错误的JSON(并且错误,我的意思是JSON可以被解析为对象,但是你想要在该对象中改变某些东西)你可以尝试添加" 拦截器 "
.config(function ($httpProvider) {
$httpProvider.interceptors.push(function($q) {
return {
'request': function(config) {
// here you can edit the request.
return config;
},
'response': function(response) {
// response.data will hold your bad data
// you could edit it
response.data = fix(response.data);
// return the correct data.
return response;
}
};
});
})
Run Code Online (Sandbox Code Playgroud)
请注意,您还可以覆盖默认转换
另外,请务必:
// Whitelist the JSONP endpoint that we are using to show that we trust it
.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'https://your.api.url/**'
]);
}])
Run Code Online (Sandbox Code Playgroud)
如果一切顺利,你可以致电:
//uncomment {jsonpCallbackParam: 'callback'} if your jsonp callback
//parameter at the backend uses some other name but the default 'callback'
$http.jsonp(https://your.api.url/*,{jsonpCallbackParam: 'callback'}*/)
.then(function(response) {
$scope.status = response.status;
$scope.data = response.data;
}, function(response) {
$scope.data = response.data || 'Request failed';
$scope.status = response.status;
});
Run Code Online (Sandbox Code Playgroud)