【发布时间】:2020-08-29 16:27:16
【问题描述】:
我有 2 个对象:
const subscription = {
endpoint: "dfksjfklsjkld",
keys: {
pkey: "dfsfsdfsf",
auth: "dfsdfsdfsd"
}
};
const extra = {
email: "dfsdfs",
ip:"231342.342.342.34"
};
我想把 extra 对象放在订阅中,所以它看起来像:
subsciption = {
endpoint: ......
keys: {...},
extra: {
email:....,
ip: .....
}
}
然后我需要将其作为 http 请求的正文发送:
const response = await fetch(url, {
method: "PUT",
mode: "no-cors",
cache: "no-cache",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
redirect: "follow",
referrerPolicy: "no-referrer",
body: JSON.stringify(subscription),
});
但是我发现不管我做什么,我总是在JSON.stringify()的过程中丢失订阅里面的额外属性。
我知道原因:这是因为额外对象中的属性不可枚举。
到目前为止,我已经尝试过:
1.使用传播:
newSub = {
...subscription,
...extra
}
但是newSub的内容会和extra完全一样,subscription的属性都丢失了。
2.将toJSON函数添加到我生成额外对象的地方
getExtra() : {
.......
return {
city: ipObject.city,
country: ipObject.country_name,
ip: ipObject.ip,
lat: ipObject.latitude,
lng: ipObject.longitude,
org: ipObject.org,
postal: ipObject.postal,
region: ipObject.region,
toJSON: () => {
return this;
}
};
}
完全没有效果。
我在这里附上我的代码:
async function updateSubscription() {
try {
const allowed = await askForPermission();
if (!allowed) return;
let subscription = await getSubscription();
if (!subscription) return;
// email
const email = getEmail();
if (!email || !validateEmail(email)) {
alert("huh...so how are you going to receive notifications?");
return;
}
// ip
let ipObject = await getIP();
let extra = {};
if (ipObject) {
ipObject.email = email;
extra = ipObject;
} else {
extra.email = email;
}
console.log("extra: ", extra);
// var newSubscription = Object.assign({}, subscription, {extra});
// const newSubscription = {
// ...subscription,
// extra
// };
let newSubscription = subscription;
newSubscription["extra"] = extra;
console.log("new subscription1: ", newSubscription);
console.log("new subscription1 stringified: ", JSON.stringify(newSubscription));
const successful = await saveRegistration(newSubscription);
if (successful) alert("you have successfully subscribed to the DC monitor");
else alert("shit happens, try it later");
} catch (err) {
console.log("updateSubscription() failed: ", err);
}
}
async function getSubscription() {
console.log("try to get subscription");
try {
const swRegistration = await navigator.serviceWorker.ready;
const pushSubscription = await swRegistration.pushManager.getSubscription();
console.log("pushSubscription: ", pushSubscription);
return pushSubscription;
} catch (error) {
console.log("getSubscription() error: ", error);
return null;
}
}
更新
1.尝试了另外一种方法:
var newSubscription = Object.assign({}, subscription, {extra});
console.log("subscription: ", newSubscription);
console.log("subscription stringified: ", JSON.stringify(newSubscription));
这是输出截图:
2.还有这个:
const newSubscription = {
...subscription,
extra
};
console.log("new subscription: ", newSubscription);
console.log("new subscription stringified: ", JSON.stringify(newSubscription));
这是输出的截图:
3.用字符串索引方式:
let newSubscription = subscription;
newSubscription["extra"] = extra;
console.log("new subscription1: ", newSubscription);
console.log("new subscription1 stringified: ", JSON.stringify(newSubscription));
【问题讨论】:
-
为什么额外的属性不可枚举?它是一种什么样的特殊物体?
-
subscriptionObject是什么? -
subscriptionObject设置在哪里? -
啊,真不错
-
也许从该对象显式复制您需要的属性?由于它是一个宿主对象,因此您无法对它的实现方式做出任何假设(我认为)。根据规范,它实际上实现了自己的 JSON 序列化过程。所以也许你想改用
sub = subscription.toJSON(); sub.extra = extra; JSON.stringify(sub)。
标签: javascript json stringify