如何在 JavaScript 中安全地将任何内容转换为字符串

发布于 2024-10-05 06:31:16 字数 246 浏览 8 评论 0原文

如果我有:

var test = {toString: function(){alert("evil code"); return "test";}};

如何将 test 转换为字符串?不调用 test.toString() 也不使用 typeof x == "string" 检查,因为我想允许非字符串。

注意:这适用于处理内容页 js 范围中的对象的 FF 扩展。

If I have:

var test = {toString: function(){alert("evil code"); return "test";}};

how can I convert test to a string? without calling test.toString() and without using a typeof x == "string" check since I want to allow non strings.

Note: this is for a FF extension dealing with objects from a content page's js scope.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

鹤舞 2024-10-12 06:31:16

遗憾的是,@Matthew Flaschen(目前已接受)的答案不适用于 ES6 / ES2015 中的 Symbol 类:

console.log("" + Symbol("foo"));
// results in an exception: 
//   `Uncaught TypeError: Cannot convert a Symbol value to a string` 
// (at least in Chrome as of this writing).

https://jsfiddle.net/L8adq9y4/

(我不知道为什么,因为 Symbol 有一个非常好的 toString() 方法:)

console.log(Symbol("foo").toString());

https://jsfiddle.net/v1rqfhru/

不过有一个解决方案:String()函数似乎能够将任何值(至少是我尝试过的值)转换为String。如果存在,它甚至会调用 toString()

console.log(String("A String"));
console.log(String(undefined));
console.log(String(null));
console.log(String({value: "An arbitrary object"}));
console.log(String({toString: function(){return "An object with a toString() method";}}));
console.log(String(function(){return "An arbitrary function"}));

https://jsfiddle.net/6uc83tsc/

因此,将您喜欢的任何内容传递到 String() 中,您将得到一个非常好的结果。

Sadly, @Matthew Flaschen's (currently accepted) answer does not work with the Symbol class from ES6 / ES2015:

console.log("" + Symbol("foo"));
// results in an exception: 
//   `Uncaught TypeError: Cannot convert a Symbol value to a string` 
// (at least in Chrome as of this writing).

https://jsfiddle.net/L8adq9y4/

(I have no idea why, as Symbol has a perfectly good toString() method:)

console.log(Symbol("foo").toString());

https://jsfiddle.net/v1rqfhru/

There's a solution though: the String() function seems to be able to convert any value (at least out of the ones I tried) into a String. It will even call toString() if it exists:

console.log(String("A String"));
console.log(String(undefined));
console.log(String(null));
console.log(String({value: "An arbitrary object"}));
console.log(String({toString: function(){return "An object with a toString() method";}}));
console.log(String(function(){return "An arbitrary function"}));

https://jsfiddle.net/6uc83tsc/

So, pass anything you like into String() and you'll get a pretty good result.

小糖芽 2024-10-12 06:31:16

JavaScript 允许您修改脚本可访问的几乎任何对象的属性,包括 Object.prototype 本身,这意味着任何对象都容易受到“邪恶代码”的攻击你解释的方式。

只有原语才能保证安全,因此确保“邪恶代码”永远不会执行的唯一方法是执行以下操作:

function safeToString(x) {
  switch (typeof x) {
    case 'object':
      return 'object';
    case 'function':
      return 'function';
    default:
      return x + '';
  }
}

JavaScript allows you to modify the properties of pretty much any object that is accessible to your script, including Object.prototype itself, meaning any object is vulnerable to "evil code" in the manner that you explained.

Only primitives are guaranteed to be safe, so the only way to ensure that "evil code" is never executed is to do something like this:

function safeToString(x) {
  switch (typeof x) {
    case 'object':
      return 'object';
    case 'function':
      return 'function';
    default:
      return x + '';
  }
}
浮华 2024-10-12 06:31:16

一种选择是:

Object.prototype.toString.call(test)

这给出:

"[object Object]"

在测试的情况下。基本上,它只是提供类型信息。但是,我想知道这里的确切场景是什么。邪恶对象是如何加载到页面中的?如果他们可以在页面上执行任意代码,那么您基本上就不走运了。除此之外,还可以重新定义Object.prototype.toString

One option is:

Object.prototype.toString.call(test)

This gives:

"[object Object]"

in the case of test. Basically, it just gives type information. However, I wonder what the exact scenario is here. How is the evil object getting loaded into the page? If they can execute arbitrary code on the page, you're basically out of luck. Among other things, it is then possible to redefine Object.prototype.toString.

说不完的你爱 2024-10-12 06:31:16

您的 (toString: function(){alert("evil code"); return "test";}) 甚至没有在这里进行解析,它会引发语法错误。我认为您想使用 {} 而不是 ()

通常,您可以使用空字符串和加号运算符来执行强制转换:

""+test;
""+2; // "2"
""+4.5 // "4.5"
""+[1, 2, 3] // "1,2,3"
""+{} // '[object Object]'

但在这里,没有真正的方法可以安全地转换对象。

您可以使用delete test.toString来摆脱覆盖的方法,之后它将回退到正常的toString方法,该方法返回'[object Object] '。您还可以通过 test.toString.toString()toString 方法本身转换为字符串。

"function () { alert("evil code"); return "test"; }"

这取决于你到底想在这里做什么。

Your (toString: function(){alert("evil code"); return "test";}) doesn't even get parsed here, it throws a syntax error. I think you wanted to use {} instead of ().

Normally you could use an empty string and the plus operator to perform a cast:

""+test;
""+2; // "2"
""+4.5 // "4.5"
""+[1, 2, 3] // "1,2,3"
""+{} // '[object Object]'

But here, there's no real way to convert the object safely.

You can use delete test.toString to get rid of the overridden method, after that it will fall back to the normal toString method which returns '[object Object]'. You can also convert the toString method itself into a string via test.toString.toString().

"function () { alert("evil code"); return "test"; }"

It's up to you what you exactly want to do here.

沫雨熙 2024-10-12 06:31:16

您只能检查 undefined 情况并将其转换为使用 String 构造函数
像这样。

let a = [1,2,3]

String(a)

例外情况:String(undefined) --> “未定义”

希望有帮助

You can check only undefined cases and convert it to using String constructor
like this.

let a = [1,2,3]

String(a)

Exceptional case : String(undefined) --> "undefined"

Hope it helps

‖放下 2024-10-12 06:31:16

您可以使用 lodash toString 方法。

_.toString(null);
// => ''

_.toString(-0);
// => '-0'

_.toString([1, 2, 3]);
// => '1,2,3'

文档链接

You can use lodash toString method.

_.toString(null);
// => ''

_.toString(-0);
// => '-0'

_.toString([1, 2, 3]);
// => '1,2,3'

Link to documentation

嘿咻 2024-10-12 06:31:16

在 JavaScript 中,函数 String 是双面的。

  • 如果作为构造函数调用,它将创建一个对象。
  • 如果作为函数调用,if 会将每个值强制转换为原始字符串。
console.log(typeof new String())
console.log(typeof String())

因此,只需使用 String(anything) without new 即可。

In JavaScript the function String is Janus-faced.

  • If called as a constructor it will create an object.
  • If called as a function if will coerces every value into a primitive string.

console.log(typeof new String())
console.log(typeof String())

So just use String(anything) without new.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文