当通过Javascript输出JSON内容时,我应该在服务器端还是在客户端进行HTML转义?

时间:2022-01-16 16:20:27

I have an application that consists of a server-side REST API written in PHP, and some client-side Javascript that consumes this API and uses the JSON it produces to render a page. So, a pretty typical setup.

我有一个应用程序,它由用PHP编写的服务器端REST API和一些客户端Javascript组成,这些Javascript使用这个API并使用它生成的JSON来呈现页面。这是一个很典型的设置。

The data provided by the REST API is "untrusted", in the sense that it is fetching user-provided content from a database. So, for example, it might fetch something like:

REST API提供的数据是“不可信的”,因为它是从数据库中获取用户提供的内容。例如,它可以获取如下内容:

{
    "message": "<script>alert("Gotcha!")</script>"
}

Obviously, if my client-side code were to render this directly into the page's DOM, I've created an XSS vulnerability. So, this content needs to be HTML-escaped first.

显然,如果我的客户端代码将它直接呈现到页面的DOM中,我就创建了一个XSS漏洞。因此,这个内容首先需要html转义。

The question is, when outputting untrusted content, should I escape the content on the server side, or the client side? I.e., should my API return the raw content, and then make it the client Javascript code's responsibility to escape the special characters, or should my API return "safe" content:

问题是,在输出不可信内容时,我应该转义服务器端还是客户端上的内容?即。,我的API应该返回原始内容,然后让客户端Javascript代码负责转义特殊字符,还是我的API应该返回“安全”内容:

{
    "message": "&lt;script&gt;alert(&#039;Gotcha!&#039;);&lt;\/script&gt;"
}

that has been already escaped?

已经逃脱了吗?

On one hand, it seems to be that the client should not have to worry about unsafe data from my server. On the other hand, one could argue that output should always be escaped at the last minute possible, when we know exactly how the data is to be consumed.

一方面,客户端似乎不必担心来自服务器的不安全数据。另一方面,有人可能会说,输出应该总是在可能的最后时刻转义,因为我们知道如何使用数据。

Which approach is correct?

哪种方法是正确的?

Note: There are plenty of questions about handling input and yes, I am aware that client-side code can always be manipulated. This question is about outputting data from my server which may not be trustable.

注意:关于处理输入有很多问题,是的,我知道客户端代码总是可以被操纵的。这个问题是关于将数据从我的服务器上输出的,这可能不可靠。

Update: I looked into what other people are doing, and it does seem that some REST APIs tend to send "unsafe" JSON. Gitter's API actually sends both, which is an interesting idea:

更新:我查看了其他人在做什么,看起来一些REST api倾向于发送“不安全”的JSON。Gitter的API实际上同时发送了这两个,这是一个有趣的想法:

[
    {
        "id":"560ab5d0081f3a9c044d709e",
        "text":"testing the API: <script>alert('hey')</script>",
        "html":"testing the API: &lt;script&gt;alert(&#39;hey&#39;)&lt;/script&gt;",
        "sent":"2015-09-29T16:01:19.999Z",
        "fromUser":{
            ...
        },"unread":false,
        "readBy":0,
        "urls":[],
        "mentions":[],
        "issues":[],
        "meta":[],
        "v":1
    }
]

Notice that they send the raw content in the text key, and then the HTML-escaped version in the html key. Not a bad idea, IMO.

注意,它们在文本键中发送原始内容,然后在html键中发送html转义版本。这主意不错,我觉得。

I have accepted an answer, but I don't believe this is a cut-and-dry problem. I would like to encourage further discussion on this topic.

我已经接受了一个答案,但我不认为这是一个一成不变的问题。我想鼓励关于这个话题的进一步讨论。

4 个解决方案

#1


12  

Escape on the client side only.

只在客户端转义。

The reason to escape on the client side is security: the server's output is the client's input, and so the client should not trust it. If you assume that the input is already escaped, then you potentially open yourself to client attacks via, for example, a malicious reverse-proxy. This is not so different from why you should always validate input on the server side, even if you also include client-side validation.

在客户端转义的原因是安全性:服务器的输出是客户端的输入,因此客户端不应该信任它。如果您假设输入已经转义,那么您可能会通过恶意反向代理(例如反向代理)对客户端进行攻击。这与为什么要始终在服务器端验证输入没有太大的不同,即使您还包括客户端验证。

The reason not to escape on the server side is separation of concerns: the server should not assume that the client intends to render the data as HTML. The server's output should be as media-neutral as possible (given the constraints of JSON and the data structure, of course), so that the client can most easily transform it into whatever format is needed.

在服务器端不转义的原因是关注点的分离:服务器不应该假设客户端打算将数据呈现为HTML。服务器的输出应该尽可能与媒体无关(当然,考虑到JSON的约束和数据结构),以便客户端能够最容易地将其转换为所需的任何格式。

#2


2  

For escaping on output:

为逃避输出:

I suggest read this and this.

我建议你看看这个和这个。

To prevent user correctly you better not only escape, but also before escaping filter it with an appropriate anti XSS library. Like htmLawed, or HTML Purifier, or any from this thread.

为了正确地防止用户,您不仅要转义,还要在转义之前使用适当的反XSS库对其进行过滤。比如htmLawed, HTML净化器,或者这个线程中的任何一个。

IMHO sanitizing should be done on user inputed data whenever you are going to show it back in web project.

当您要在web项目中显示输入数据时,应该对用户输入的数据进行IMHO清理。

should I escape the content on the server side, or the client side? I.e., should my API return the raw content, and then make it the client Javascript code's responsibility to escape the special characters, or should my API return "safe" content:

我应该转义服务器端还是客户端上的内容?即。,我的API应该返回原始内容,然后让客户端Javascript代码负责转义特殊字符,还是我的API应该返回“安全”内容:

It's better to return already escaped, and xss purified content, so:

最好是返回已经转义,并且xss净化的内容,所以:

  1. Take raw data and purify if from xss on server
  2. 获取原始数据并从服务器上的xss中进行提纯
  3. Escape it
  4. 逃避它
  5. Return to JavaScript
  6. 返回JavaScript

And also, you should notice one important thing, like a load of your site and read/write balance: for example if your client enters data once and you are going to show this data to 1M users, what do you prefer: run protection logic once before write (protect on input) on a million time each read(protect on output)?

同时,你应该注意到一个重要的事情,像一个站点的加载和读/写平衡:例如,如果您的客户端输入数据一次,你要显示这个数据为1 m用户,你喜欢什么:保护逻辑运行一次(保护输入)写在一百万年之前每个读过(输出)保护吗?

If you are going to show like 1K posts on a page and escape each on client, how well will it work on the client's mobile phone? This last one will help you to chose where to protect data on client or on server.

如果你打算在页面上显示1K个帖子,然后在客户端上转义每个帖子,那么它在客户端手机上的表现会如何呢?最后一个将帮助您选择在客户机或服务器上保护数据的位置。

#3


0  

This answer is more focused on arguing whether to do client-side escaping vs server-side, since OP seems aware of the argument against escaping on input vs output.

这个答案更侧重于讨论是否进行客户端转义与服务器端转义,因为OP似乎意识到了反对转义输入与输出的争论。

Why not escape client-side?

I would argue that escaping at the javascript level is not a good idea. Just an issue off the top of my head would be if there was an error in the sanitizing script, it would not run, and then the dangerous script would be allowed to run. So you have introduced a vector where an attacker can try to craft input to break the JS sanitizer, so that their plain script is allowed to run. I also do not know of any built-in AntiXSS libraries that run in JS. I am sure someone has made one, or could make one, but there are established server-side examples that are a little more trust-worthy. It is also worth mentioning that writing a sanitizer in JS that works for all browsers is not a trivial task.

我认为在javascript级别上转义不是一个好主意。我头顶上的一个问题是,如果在消毒脚本中出现错误,它就不会运行,然后危险的脚本就会被允许运行。因此,您引入了一个向量,攻击者可以尝试通过手工输入来破坏JS sanitizer,这样它们的普通脚本就可以运行了。我也不知道在JS中运行的任何内置的AntiXSS库。我确信有人已经做了一个,或者可以做一个,但是有一些建立的服务器端示例更值得信任。值得一提的是,在所有浏览器中编写一个用于所有浏览器的杀毒软件并不是一件简单的任务。

OK, what if you escape on both?

Escaping server-side and client-side is just kind of confusing to me, and shouldn't provide any additional security. You mentioned the difficulties with double-escaping, and I have experienced that pain before.

转义服务器端和客户端对我来说有点混乱,不应该提供任何额外的安全性。你提到了双重逃避的困难,我以前也经历过这种痛苦。

Why is server-side good enough?

Escaping server-side should be sufficient. Your point about doing it as late as possible makes some sense, but I think the drawbacks of escaping client-side are outweighed by whatever tiny benefit you may get by doing it. Where is the threat? If an attacker exists between your site and the client, then the client is already compromised since they can just send a blank html file with their script if they want. You need to do your best to send something safe, not just send the tools to deal with your dangerous data.

转义服务器端应该足够了。您关于尽可能晚地完成它的观点是有道理的,但是我认为转义客户端的缺点被您所做的任何微小的好处所抵消。威胁在哪里?如果攻击者存在于您的站点和客户端之间,那么客户端就已经被破坏了,因为如果他们想要的话,他们可以用他们的脚本发送一个空白的html文件。您需要尽最大的努力发送安全的东西,而不是仅仅发送工具来处理危险的数据。

#4


0  

TLDR; If your API is to convey formatting information, it should output HTML encoded strings. Caveat: Any consumer will need to trust your API not to output malicious code. A Content Security Policy can help with this too.

TLDR;如果您的API要传递格式化信息,那么它应该输出HTML编码的字符串。注意:任何消费者都需要相信你的API不会输出恶意代码。内容安全策略也可以帮助实现这一点。

If your API is to output only plain text, then HTML encode on the client-side (as < in the plain text also means < in any output).

如果您的API只输出纯文本,那么在客户端上对HTML进行编码(在纯文本中为 <也意味着在任何输出中为<)。< p>

Not too long, not done reading:

If you own both the API and the web application, either way is acceptable. As long as you are not outputting JSON to HTML pages without hex entity encoding like this:

如果您同时拥有API和web应用程序,两种方法都可以接受。只要你没有像这样的十六进制实体编码,就不会将JSON输出到HTML页面:

<%
payload = "[{ foo: '" + foo + "'}]"
%>
    <script><%= payload %></script>

then it doesn't matter whether the code on your server changes & to &amp; or the code in the browser changes & to &amp;.

那么,服务器上的代码是否更改为&amp并不重要或者浏览器中的代码改变了& to &

Let's take the example from your question:

让我们以你的问题为例:

[
    {
        "id":"560ab5d0081f3a9c044d709e",
        "text":"testing the API: <script>alert('hey')</script>",
        "html":"testing the API: &lt;script&gt;alert(&#39;hey&#39;)&lt;/script&gt;",
        "sent":"2015-09-29T16:01:19.999Z",

If the above is returned from api.example.com and you call it from www.example.com, as you control both sides you can decide whether you want to take the plain text, "text", or the formatted text, "html".

如果以上内容是从api.example.com返回的,您可以从www.example.com调用它,因为您控制了两边,所以您可以决定是使用纯文本、“text”还是格式化文本“html”。

It is important to remember though that any variables inserted into html have been HTML encoded server-side here. And also assume that correct JSON encoding has been carried out which stops any quote characters from breaking, or changing the context of the JSON (this is not shown in the above for simplicity).

重要的是要记住,任何插入到html中的变量都是在服务器端进行html编码的。并且还假设已经执行了正确的JSON编码,它可以阻止任何引号字符被破坏,或者改变JSON的上下文(为了简单起见,上面没有显示这一点)。

text would be inserted into the document using Node.textContent and html as Element.innerHTML. Using Node.textContent will cause the browser to ignore any HTML formatting and script that may be present because characters like < are literally taken to be output as < on the page.

文本将使用Node插入到文档中。textContent和html作为元素。innerhtml。使用节点。textContent将导致浏览器忽略可能出现的任何HTML格式和脚本,因为像 <这样的字符在页面上被作为<输出。< p>

Note your example shows user content being input as script. i.e. a user has typed <script>alert('hey')</script> into your application, it is not API generated. If your API actually wanted to output tags as part of its function, then it'd have to put them in the JSON:

注意,您的示例显示用户内容作为脚本输入。例如,用户在应用程序中输入了,它不是生成的API。如果您的API实际上想要输出标记作为其函数的一部分,那么它必须将它们放在JSON中:

"html":"<u>Underlined</u>"

And then your text would have to only output the text without formatting:

然后你的文本只能输出没有格式的文本:

"text":"Underlined"

Therefore, your API while sending information to your web application consumer is no longer transmitting rich text, only plain text.

因此,在向web应用程序使用者发送信息时,您的API不再传输富文本,而只传输纯文本。

If, however, a third party was consuming your API, then they may wish to get the data from your API as plain text because then they can set Node.textContent (or HTML encode it) on the client-side themselves, knowing that it is safe. If you return HTML then your consumer needs to trust you that your HTML does not contain any malicious script.

但是,如果第三方正在使用您的API,那么他们可能希望以纯文本的形式从您的API获取数据,因为这样他们就可以设置Node。textContent(或HTML编码)在客户端本身上,知道它是安全的。如果您返回HTML,那么您的消费者需要信任您的HTML不包含任何恶意脚本。

So if the above content is from api.example.com, but your consumer is a third party site, say, www.example.edu, then they may feel more comfortable taking in text rather than HTML. Your output may need to be more granularly defined in this case, so rather than outputting

因此,如果上面的内容来自于api.example.com,但是你的消费者是第三方网站,比如www.example.edu,那么他们可能会更愿意接受文本而不是HTML。在这种情况下,您的输出可能需要更精确地定义,因此而不是输出。

"text":"Thank you Alice for signing up."

You would output

你会输出

[{ "name", "alice",
"messageType": "thank_you" }]

Or similar so you are not defining the layout in your JSON any longer, you are just conveying the information for the client-side to interpret and format using their own style. To further clarify what I mean, if all your consumer got was

或者类似,这样您就不用再用JSON定义布局了,您只是将信息传递给客户端,以便客户端使用它们自己的样式来解释和格式化。为了进一步阐明我的意思,如果你的消费者得到了。

"text":"Thank you Alice for signing up."

and they wanted to show names in bold, it would be very tricky for them to accomplish this without complex parsing. However, with defining API outputs on a granular level, the consumer can take the relevant pieces of output like variables, and then apply their own HTML formatting, without having to trust your API to only output bold tags (<b>) and not to output malicious JavaScript (either from the user or from you, if you were indeed malicious, or if your API had been compromised).

他们想用粗体显示名字,如果没有复杂的解析,他们就很难完成这个任务。然而,随着粒度级别上定义API输出,顾客可以把相关部分的输出变量,然后运用自己的HTML格式,而不需要信任你的API只输出粗体标签(< b >),而不是输出恶意JavaScript(从用户或从你,如果你确实是恶意的,或如果你的API被破坏)。

#1


12  

Escape on the client side only.

只在客户端转义。

The reason to escape on the client side is security: the server's output is the client's input, and so the client should not trust it. If you assume that the input is already escaped, then you potentially open yourself to client attacks via, for example, a malicious reverse-proxy. This is not so different from why you should always validate input on the server side, even if you also include client-side validation.

在客户端转义的原因是安全性:服务器的输出是客户端的输入,因此客户端不应该信任它。如果您假设输入已经转义,那么您可能会通过恶意反向代理(例如反向代理)对客户端进行攻击。这与为什么要始终在服务器端验证输入没有太大的不同,即使您还包括客户端验证。

The reason not to escape on the server side is separation of concerns: the server should not assume that the client intends to render the data as HTML. The server's output should be as media-neutral as possible (given the constraints of JSON and the data structure, of course), so that the client can most easily transform it into whatever format is needed.

在服务器端不转义的原因是关注点的分离:服务器不应该假设客户端打算将数据呈现为HTML。服务器的输出应该尽可能与媒体无关(当然,考虑到JSON的约束和数据结构),以便客户端能够最容易地将其转换为所需的任何格式。

#2


2  

For escaping on output:

为逃避输出:

I suggest read this and this.

我建议你看看这个和这个。

To prevent user correctly you better not only escape, but also before escaping filter it with an appropriate anti XSS library. Like htmLawed, or HTML Purifier, or any from this thread.

为了正确地防止用户,您不仅要转义,还要在转义之前使用适当的反XSS库对其进行过滤。比如htmLawed, HTML净化器,或者这个线程中的任何一个。

IMHO sanitizing should be done on user inputed data whenever you are going to show it back in web project.

当您要在web项目中显示输入数据时,应该对用户输入的数据进行IMHO清理。

should I escape the content on the server side, or the client side? I.e., should my API return the raw content, and then make it the client Javascript code's responsibility to escape the special characters, or should my API return "safe" content:

我应该转义服务器端还是客户端上的内容?即。,我的API应该返回原始内容,然后让客户端Javascript代码负责转义特殊字符,还是我的API应该返回“安全”内容:

It's better to return already escaped, and xss purified content, so:

最好是返回已经转义,并且xss净化的内容,所以:

  1. Take raw data and purify if from xss on server
  2. 获取原始数据并从服务器上的xss中进行提纯
  3. Escape it
  4. 逃避它
  5. Return to JavaScript
  6. 返回JavaScript

And also, you should notice one important thing, like a load of your site and read/write balance: for example if your client enters data once and you are going to show this data to 1M users, what do you prefer: run protection logic once before write (protect on input) on a million time each read(protect on output)?

同时,你应该注意到一个重要的事情,像一个站点的加载和读/写平衡:例如,如果您的客户端输入数据一次,你要显示这个数据为1 m用户,你喜欢什么:保护逻辑运行一次(保护输入)写在一百万年之前每个读过(输出)保护吗?

If you are going to show like 1K posts on a page and escape each on client, how well will it work on the client's mobile phone? This last one will help you to chose where to protect data on client or on server.

如果你打算在页面上显示1K个帖子,然后在客户端上转义每个帖子,那么它在客户端手机上的表现会如何呢?最后一个将帮助您选择在客户机或服务器上保护数据的位置。

#3


0  

This answer is more focused on arguing whether to do client-side escaping vs server-side, since OP seems aware of the argument against escaping on input vs output.

这个答案更侧重于讨论是否进行客户端转义与服务器端转义,因为OP似乎意识到了反对转义输入与输出的争论。

Why not escape client-side?

I would argue that escaping at the javascript level is not a good idea. Just an issue off the top of my head would be if there was an error in the sanitizing script, it would not run, and then the dangerous script would be allowed to run. So you have introduced a vector where an attacker can try to craft input to break the JS sanitizer, so that their plain script is allowed to run. I also do not know of any built-in AntiXSS libraries that run in JS. I am sure someone has made one, or could make one, but there are established server-side examples that are a little more trust-worthy. It is also worth mentioning that writing a sanitizer in JS that works for all browsers is not a trivial task.

我认为在javascript级别上转义不是一个好主意。我头顶上的一个问题是,如果在消毒脚本中出现错误,它就不会运行,然后危险的脚本就会被允许运行。因此,您引入了一个向量,攻击者可以尝试通过手工输入来破坏JS sanitizer,这样它们的普通脚本就可以运行了。我也不知道在JS中运行的任何内置的AntiXSS库。我确信有人已经做了一个,或者可以做一个,但是有一些建立的服务器端示例更值得信任。值得一提的是,在所有浏览器中编写一个用于所有浏览器的杀毒软件并不是一件简单的任务。

OK, what if you escape on both?

Escaping server-side and client-side is just kind of confusing to me, and shouldn't provide any additional security. You mentioned the difficulties with double-escaping, and I have experienced that pain before.

转义服务器端和客户端对我来说有点混乱,不应该提供任何额外的安全性。你提到了双重逃避的困难,我以前也经历过这种痛苦。

Why is server-side good enough?

Escaping server-side should be sufficient. Your point about doing it as late as possible makes some sense, but I think the drawbacks of escaping client-side are outweighed by whatever tiny benefit you may get by doing it. Where is the threat? If an attacker exists between your site and the client, then the client is already compromised since they can just send a blank html file with their script if they want. You need to do your best to send something safe, not just send the tools to deal with your dangerous data.

转义服务器端应该足够了。您关于尽可能晚地完成它的观点是有道理的,但是我认为转义客户端的缺点被您所做的任何微小的好处所抵消。威胁在哪里?如果攻击者存在于您的站点和客户端之间,那么客户端就已经被破坏了,因为如果他们想要的话,他们可以用他们的脚本发送一个空白的html文件。您需要尽最大的努力发送安全的东西,而不是仅仅发送工具来处理危险的数据。

#4


0  

TLDR; If your API is to convey formatting information, it should output HTML encoded strings. Caveat: Any consumer will need to trust your API not to output malicious code. A Content Security Policy can help with this too.

TLDR;如果您的API要传递格式化信息,那么它应该输出HTML编码的字符串。注意:任何消费者都需要相信你的API不会输出恶意代码。内容安全策略也可以帮助实现这一点。

If your API is to output only plain text, then HTML encode on the client-side (as < in the plain text also means < in any output).

如果您的API只输出纯文本,那么在客户端上对HTML进行编码(在纯文本中为 <也意味着在任何输出中为<)。< p>

Not too long, not done reading:

If you own both the API and the web application, either way is acceptable. As long as you are not outputting JSON to HTML pages without hex entity encoding like this:

如果您同时拥有API和web应用程序,两种方法都可以接受。只要你没有像这样的十六进制实体编码,就不会将JSON输出到HTML页面:

<%
payload = "[{ foo: '" + foo + "'}]"
%>
    <script><%= payload %></script>

then it doesn't matter whether the code on your server changes & to &amp; or the code in the browser changes & to &amp;.

那么,服务器上的代码是否更改为&amp并不重要或者浏览器中的代码改变了& to &

Let's take the example from your question:

让我们以你的问题为例:

[
    {
        "id":"560ab5d0081f3a9c044d709e",
        "text":"testing the API: <script>alert('hey')</script>",
        "html":"testing the API: &lt;script&gt;alert(&#39;hey&#39;)&lt;/script&gt;",
        "sent":"2015-09-29T16:01:19.999Z",

If the above is returned from api.example.com and you call it from www.example.com, as you control both sides you can decide whether you want to take the plain text, "text", or the formatted text, "html".

如果以上内容是从api.example.com返回的,您可以从www.example.com调用它,因为您控制了两边,所以您可以决定是使用纯文本、“text”还是格式化文本“html”。

It is important to remember though that any variables inserted into html have been HTML encoded server-side here. And also assume that correct JSON encoding has been carried out which stops any quote characters from breaking, or changing the context of the JSON (this is not shown in the above for simplicity).

重要的是要记住,任何插入到html中的变量都是在服务器端进行html编码的。并且还假设已经执行了正确的JSON编码,它可以阻止任何引号字符被破坏,或者改变JSON的上下文(为了简单起见,上面没有显示这一点)。

text would be inserted into the document using Node.textContent and html as Element.innerHTML. Using Node.textContent will cause the browser to ignore any HTML formatting and script that may be present because characters like < are literally taken to be output as < on the page.

文本将使用Node插入到文档中。textContent和html作为元素。innerhtml。使用节点。textContent将导致浏览器忽略可能出现的任何HTML格式和脚本,因为像 <这样的字符在页面上被作为<输出。< p>

Note your example shows user content being input as script. i.e. a user has typed <script>alert('hey')</script> into your application, it is not API generated. If your API actually wanted to output tags as part of its function, then it'd have to put them in the JSON:

注意,您的示例显示用户内容作为脚本输入。例如,用户在应用程序中输入了,它不是生成的API。如果您的API实际上想要输出标记作为其函数的一部分,那么它必须将它们放在JSON中:

"html":"<u>Underlined</u>"

And then your text would have to only output the text without formatting:

然后你的文本只能输出没有格式的文本:

"text":"Underlined"

Therefore, your API while sending information to your web application consumer is no longer transmitting rich text, only plain text.

因此,在向web应用程序使用者发送信息时,您的API不再传输富文本,而只传输纯文本。

If, however, a third party was consuming your API, then they may wish to get the data from your API as plain text because then they can set Node.textContent (or HTML encode it) on the client-side themselves, knowing that it is safe. If you return HTML then your consumer needs to trust you that your HTML does not contain any malicious script.

但是,如果第三方正在使用您的API,那么他们可能希望以纯文本的形式从您的API获取数据,因为这样他们就可以设置Node。textContent(或HTML编码)在客户端本身上,知道它是安全的。如果您返回HTML,那么您的消费者需要信任您的HTML不包含任何恶意脚本。

So if the above content is from api.example.com, but your consumer is a third party site, say, www.example.edu, then they may feel more comfortable taking in text rather than HTML. Your output may need to be more granularly defined in this case, so rather than outputting

因此,如果上面的内容来自于api.example.com,但是你的消费者是第三方网站,比如www.example.edu,那么他们可能会更愿意接受文本而不是HTML。在这种情况下,您的输出可能需要更精确地定义,因此而不是输出。

"text":"Thank you Alice for signing up."

You would output

你会输出

[{ "name", "alice",
"messageType": "thank_you" }]

Or similar so you are not defining the layout in your JSON any longer, you are just conveying the information for the client-side to interpret and format using their own style. To further clarify what I mean, if all your consumer got was

或者类似,这样您就不用再用JSON定义布局了,您只是将信息传递给客户端,以便客户端使用它们自己的样式来解释和格式化。为了进一步阐明我的意思,如果你的消费者得到了。

"text":"Thank you Alice for signing up."

and they wanted to show names in bold, it would be very tricky for them to accomplish this without complex parsing. However, with defining API outputs on a granular level, the consumer can take the relevant pieces of output like variables, and then apply their own HTML formatting, without having to trust your API to only output bold tags (<b>) and not to output malicious JavaScript (either from the user or from you, if you were indeed malicious, or if your API had been compromised).

他们想用粗体显示名字,如果没有复杂的解析,他们就很难完成这个任务。然而,随着粒度级别上定义API输出,顾客可以把相关部分的输出变量,然后运用自己的HTML格式,而不需要信任你的API只输出粗体标签(< b >),而不是输出恶意JavaScript(从用户或从你,如果你确实是恶意的,或如果你的API被破坏)。