JSON.Parse不处理非法字符

时间:2016-01-10 16:21:55

标签: javascript json encoding error-handling

我使用base64解码字符串。为了测试我的错误处理,我在字符串中添加了一些额外的字符,结果是

i��{"alg":"RS256","kid":"c818a52e5a3a9cbb853ed47a326376c86cb0b5e6"}

通过JSON.Parse推送它将导致undefined和JSON.parse然后抛出一个TypeError,说它无法调用未定义的toString()。

尝试/捕捉不是这个。我该怎么办?

太明确了这一点在node.js后端运行。

[编辑]

更多信息。这是我发送给API的json。以下将正确验证,因为它是base64编码。但是,如果我在前面添加一些随机字母,它会明显搞砸,但我如何检查它?:

{
    "payload" : {
        "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImM4MThhNTJlNWEzYTljYmI4NTNlZDQ3YTMyNjM3NmM4NmNiMGI1ZTYifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXRfaGFzaCI6IjVIcm8tZk5xWGdkLXJLdTBfdVV1dkEiLCJhdWQiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDM1MDQ2NTcwODY3NDQyNDk0NTgiLCJhenAiOiI0MDc0MDg3MTgxOTIuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJpYXQiOjE0NTI0MzQ0NDUsImV4cCI6MTQ1MjQzODA0NX0.clvcKwE2SxaU3PLAcLzJklURdZQV9CZwlWPDCXXATE7gShflnrWWase0Q_s3d8B5eR-LDizwcB5ViFc-xHuMIj7Ro1gaysyv4Yg5hCJe_aFGJel91j7Jefiwp205dICTpnCodWHfDoIgnSLSAHUo2Q0l5hbS38R7pBAoPS3vIyG7RxkHGYVxp55Rkd0wgX5cXB-_WkLwSsrLN5uOyOMpZ8xBK9IMhfwQWvNaLcAIluuIeeIVMY2nVtcicPWHCSt3AgVHqkW4bb-e-b6jC-LuLBs0aB8otXFX9PQV3uEwSb6vKO4DHDUZR-Znwi0OlKurlGpsT-KvpM_kCV3RVp9cDQ"
    },
    "username":"somelongusernamethatisunique",
    "useragent":"Android"
}

然后解析它的代码如下:

function(payload) {
  var segments = payload.id_token.split('.');
  var config = request.getAsync(
      'https://accounts.google.com/.well-known/openid-configuration')
    .then(function(result) {
      var response = JSON.parse(result.body);
      return request.getAsync(response.jwks_uri);
    }).then(function(result) {
      return JSON.parse(result.body);
    }).caught(SyntaxError, function(e) {
      throw e;
    })

  var header = new Promise(function(resolve, reject) {
    try {
      var base64string = base64urlDecode(segments[0]);
      console.log(base64string);
      resolve(JSON.parse(base64string));
    } catch (e) {
      reject(e);
    }
  }).caught(SyntaxError, function(e) {
    throw e;
  })

  return Promise.join(config, header, function(response, header) {
    return new Promise(function(resolve, reject) {
      var key = '';
      for (var i = 0; i < response.keys.length; i++) {
        if (response.keys[i].kid === header.kid) {
          key = response.keys[i];
          break;
        }
      }

      if (jws.verify(payload.id_token, key)) {
        var info = JSON.parse(base64urlDecode(segments[1]));
        resolve(info.sub);
      } else {
        reject();
      }
    });
  });
}
};

function base64urlDecode(str) {
  return new Buffer(base64urlUnescape(str), 'base64').toString();
};

function base64urlUnescape(str) {
  str += Array(5 - str.length % 4).join('=');
  return str.replace(/\-/g, '+').replace(/_/g, '/');
}

1 个答案:

答案 0 :(得分:1)

如果你想假装你的代码从某个地方收到了那个字符串,你应该可以用单引号包装它:

var badInput = 'i��{"alg":"RS256","kid":"c818a52e5a3a9cbb853ed47a326376c86cb0b5e6"}';

badInput设置为混乱的JSON源作为字符串。然后try / catch围绕JSON.parse()的呼叫应该按预期执行:

try {
  var result = JSON.parse(badInput);
}
catch(x) {
  alert("Error test: " + x);
}

JSFiddle demonstration.