英文:
How to decode a base64 encoded string returned from an api correctly
问题
const decodedObject: {
foo?: string;
} = JSON.parse(
Buffer.from(encodedString.replace("b'", '').replace("'", ''), 'base64').toString(),
);
英文:
Having a base64 string encoded JSON like object coming from a python API, what is the correct way to decode and parse the encoded JSON in javascript?
Python makes it a byte string literal by adding b
prefix and additional apostrophes.
I have written the following function using Buffer.from
and buf.toString
methods, which is working fine, but the problem is, the string I receive from the API has b'<encoded-string>'
format. With the initial b
and the apostrophes('
).
const decodedObject: {
foo?: string;
} = JSON.parse(
Buffer.from(encodedString.replace("b'", '').replace("'", ''), 'base64').toString(),
);
atob
and btoa
seems deprecated I as understand from the warning in my IDE. That's why I used Buffer methods
So, my question is: Removing those apostrophes and b
manually didn't feel right. Is there something I might be missing?
For example creating the encoded base64 in python:
>>> import base64
>>> "https://example.com?encoded={}".format(base64.b64encode(str({"foo":"bar"}).encode('utf-8')))
"https://example.com?encoded=b'eydmb28nOiAnYmFyJ30='"
In order to decode that base64 in javascript, I need to first remove those prefix and apostrophes.
> console.log(atob('eydmb28nOiAnYmFyJ30='))
{'foo': 'bar'}
答案1
得分: 2
这里的问题是,你的Python代码在假装字符串是JSON,而实际上没有使用json
库生成正确的JSON。
所以,让我们来修复这个问题:
import base64
import json
data = { "foo": "bar" }
encoded_value = base64.b64encode(json.dumps(data))
url = f"https://example.com?encoded={encoded_value}"
至此,encoded
URL查询参数现在是JS端上的一个普通、轻松解码的值,因为我们可以保证它是正确的JSON,只是经过了base64编码。
这意味着为了在JS端解析它,我们只需按照以下明显的步骤进行操作:
- 获取查询值,
- 解码它,
- 将其解析为JSON
因此:
// 我不知道你是在运行Node、浏览器、Deno等。
// 所以替换为window.location或你的框架的路径对象。
const url = new URL(request.path)
// 获取编码值
const query = new URLSearchParams(url.search)
const encoded = query.get(`encoded`)
// 将其转换回JSON字符串并解析
const decoded = base64Decode(encoded); // 再次强调,不知道你在哪里运行这个代码。
try {
const unpacked = JSON.parse(decoded);
console.log(unpacked); // { foo: "bar" }
} catch (e) {
// 一定要在try/catch中运行JSON.parse,因为它可能会抛出异常。
}
需要注意的是,base64Decode(encoded)
是一个占位符,代表你使用的任何base64库。
英文:
The problem here is that your Python code is pretending strings are JSON, instead of actually using the json
library to generate proper JSON.
So, let's fix that:
import base64
import json
data = { "foo": "bar" }
encoded_value = base64.b64encode(json.dumps(data))
url = f"https://example.com?encoded={encoded_value}"
And done, the encoded
URL query argument is now a normal, trivially decoded value on the JS side, because we're guaranteed that it's proper JSON, just base64 encoded.
Which means that in order to unpack that on the JS side, we just run through the obvious steps:
- get the query value,
- decode it,
- parse it as JSON
So:
// I have no idea if you're running Node, a browser, Deno, etc.
// so substitute window.location or your framework's path object.
const url = new URL(request.path)
// get the encoded value
const query = new URLSearchParams(url.search)
const encoded = query.get(`encoded`)
// turn it back into a JSON string and parse that
const decoded = base64Decode(encoded); // again, no idea where you're running this.
try {
const unpacked = JSON.parse(decoded);
console.log(unpacked); // { foo: "bar" }
} catch (e) {
// ALWAYS run JSON.parse in a try/catch because it can, and will, throw.
}
Noting that that base64Decode(encoded)
is a stand-in for whatever base64 library you're using.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论