使用内容安全策略将服务器数据传递给客户端脚本
Passing server data to client script with Content Security Policy
在 Web 服务器 (https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 上设置内容安全策略 header 后,现代浏览器会阻止任何内联脚本。建议将所有javascript放在.js文件中,并配置策略授权这些.js文件所在的域。
很好,但我的问题是我们应该如何将数据从 server-side 应用程序传递到客户端脚本?
例如,如果我想调用一个以 server-side 值作为输入的 js 函数,我仍然必须在页面 body 已被阻止。
<body>
...
<input type="button" value="Test" onclick="DoSomething('@ViewData["SomeValue"]');" />
...
</body>
我找到了一些在脚本 src 属性查询字符串 (http://feather.elektrum.org/book/src.html) 中传递数据的方法,但我不确定这是最佳解决方案。
我特别担心 src 查询字符串中变量的缓存问题。有更好的方法吗?
不是让服务器输出内联 JavaScript 并动态插入值,您需要 JavaScript 调用服务器上的端点(例如 REST API) returns 它需要的数据。该限制仅适用于内联脚本;您仍然可以在运行时使用 XMLHttpRequest 从服务器获取任意数据。
或者,您可以提供一个动态生成的 js 文件,它可以像内联脚本一样工作,但单独执行。这是一种可能性,但有点 hack,并没有真正的优势。
由于在第一个请求中有初始数据是非常常见的,这里有一个简单的方法。当您只需要数据时,无需实际脚本。
<script type="application/json" id="data">{"foo": "bar"}</script>
然后在您的 JavaScript 文件中
var data = JSON.parse(document.querySelector('#data').innerHTML);
alert(data.foo);
五年后,但这是我决定的总体策略:
对于在页面加载时转到客户端脚本的服务器值 运行 我在页面中使用了禁用的输入字段:
<input id='init_data' type='hidden' disabled value='@ViewData["SomeValue"]'>
避免任何内联 javascript,然后在页面加载发生后获取值,例如
$(document).ready(function(){
let myValue = $("#init_data").val();
DoSomething(myValue);
});
为了替换需要一些服务器生成值的 'onClick' 类型事件,我将 onClick 属性替换为 'data-click' 并添加 'event_xxxx' class 来附加触发事件至:
<input class='event_xxxx' type='button' data-click='@ViewData["SomeValue"]'>
$(document).ready(function(){
$(".event_xxxx").click(function() {
let myData = $(this).attr('data-click');
<do things>
} ;
});
我使用 id 作为初始数据,因为这通常与页面加载时发生的单个事件有关,而我的 onClicks 通常用于多个项目,因此我将相同的 class 附加到那些。
在 Web 服务器 (https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 上设置内容安全策略 header 后,现代浏览器会阻止任何内联脚本。建议将所有javascript放在.js文件中,并配置策略授权这些.js文件所在的域。
很好,但我的问题是我们应该如何将数据从 server-side 应用程序传递到客户端脚本?
例如,如果我想调用一个以 server-side 值作为输入的 js 函数,我仍然必须在页面 body 已被阻止。
<body>
...
<input type="button" value="Test" onclick="DoSomething('@ViewData["SomeValue"]');" />
...
</body>
我找到了一些在脚本 src 属性查询字符串 (http://feather.elektrum.org/book/src.html) 中传递数据的方法,但我不确定这是最佳解决方案。 我特别担心 src 查询字符串中变量的缓存问题。有更好的方法吗?
不是让服务器输出内联 JavaScript 并动态插入值,您需要 JavaScript 调用服务器上的端点(例如 REST API) returns 它需要的数据。该限制仅适用于内联脚本;您仍然可以在运行时使用 XMLHttpRequest 从服务器获取任意数据。
或者,您可以提供一个动态生成的 js 文件,它可以像内联脚本一样工作,但单独执行。这是一种可能性,但有点 hack,并没有真正的优势。
由于在第一个请求中有初始数据是非常常见的,这里有一个简单的方法。当您只需要数据时,无需实际脚本。
<script type="application/json" id="data">{"foo": "bar"}</script>
然后在您的 JavaScript 文件中
var data = JSON.parse(document.querySelector('#data').innerHTML);
alert(data.foo);
五年后,但这是我决定的总体策略:
对于在页面加载时转到客户端脚本的服务器值 运行 我在页面中使用了禁用的输入字段:
<input id='init_data' type='hidden' disabled value='@ViewData["SomeValue"]'>
避免任何内联 javascript,然后在页面加载发生后获取值,例如
$(document).ready(function(){
let myValue = $("#init_data").val();
DoSomething(myValue);
});
为了替换需要一些服务器生成值的 'onClick' 类型事件,我将 onClick 属性替换为 'data-click' 并添加 'event_xxxx' class 来附加触发事件至:
<input class='event_xxxx' type='button' data-click='@ViewData["SomeValue"]'>
$(document).ready(function(){
$(".event_xxxx").click(function() {
let myData = $(this).attr('data-click');
<do things>
} ;
});
我使用 id 作为初始数据,因为这通常与页面加载时发生的单个事件有关,而我的 onClicks 通常用于多个项目,因此我将相同的 class 附加到那些。