有时我必须将一些变量从 PHP 传递到 JS 脚本。现在我这样做了:
var js-variable = "<?php echo $php-variable; ?>";
但这非常难看,我无法将我的 JS 脚本隐藏在 .js 文件中,因为它必须由 PHP 解析。处理此问题的最佳解决方案是什么?
有时我必须将一些变量从 PHP 传递到 JS 脚本。现在我这样做了:
var js-variable = "<?php echo $php-variable; ?>";
但这非常难看,我无法将我的 JS 脚本隐藏在 .js 文件中,因为它必须由 PHP 解析。处理此问题的最佳解决方案是什么?
如果您不想使用 PHP 生成 javascript(并且不介意额外调用您的网络服务器),请使用 AJAX 获取数据。
如果您确实想使用 PHP,请始终在输出前使用 json_encode 进行编码。
<script>
var myvar = <?php echo json_encode($myVarValue); ?>;
</script>
请使用 rest/rpc api 并将 json 传递给您的 js。如果您使用 jquery,可以通过以下方式完成:
休息.php
<?php echo "{name:biplav}" ?>
然后从你的 js 中进行如下调用:
var js_var;
$.get("rest.php", function(data) {
js_var=data;
});
这是我能想到的最简单的例子。
<?php
// filename: output-json.php
header('content-type:application/json;charset=utf-8');
printf('var foo = %s;', json_encode($foo, JSON_PRETTY_PRINT));
json_encode
是一个强大的函数,可确保输出被编码和格式化为有效的 javascript / json。content-type 标头告诉浏览器如何解释响应。
如果您的响应是真正的 JSON,例如:
{"foo": 5}
然后将其声明为content-type:application/json;charset=utf-8
. JSON 解析速度更快,与 javascript 相比,被 xss 攻击的可能性要小得多。但是,如果您需要在响应中使用真正的 javascript,例如:
var obj = {foo: 5};
然后将其声明为content-type:text/javascript;charset=utf-8
您可以像文件一样链接到它:
<script src="output-json.php"></script>
或者,可以方便地将值直接嵌入到您的 html 中,而不是发出单独的 http 请求。这样做:
<script>
<?php printf('var foo = %s;', json_encode($foo, JSON_HEX_TAG | JSON_PRETTY_PRINT)) ?>
</script>
JSON_HEX_TAG
如果通过 <script> 标签嵌入到您的 html 中,请务必使用,否则您将面临 xss 注入攻击的风险。您可能还需要使用其他标志来提高安全性,具体取决于您在其中使用它的上下文:JSON_HEX_AMP, JSON_HEX_QUOT, JSON_HEX_APOS
. 这些标志使响应的可读性降低,但通常有利于安全性和兼容性,因此您可能应该只使用它们。
我真的想强调声明内容类型和可能使用JSON_HEX_TAG
标志的重要性,因为它们都可以帮助减轻 xss 注入。
除非您想引诱 xss 攻击,否则不要这样做:
<script>
var myvar = <?php echo json_encode($myVarValue); ?>;
</script>
在我看来,如果你需要直接在你的 JS 中传递一个变量,可能你的 web 应用程序设计得不好。
所以,我有两个提示: * 使用 JSON 文件进行一般配置,比如/js/conf/userprefs.json
{
"avatar": "/img/users/123/avatar.jpg",
"preferred_color": "blue"
// ...
}
使用 Symfony2 等 PHP 框架,您可以决定路由配置中的格式,将变量的输出留给模板引擎(如 Twig)。
我为 Symfony2 用户做了一个例子,但这可以被任何程序员使用:
路由.yml
userprefs:
pattern: /js/confs/userprefs.{_format}
defaults: { _controller: CoreBundle:JsonPrefs:User, _format: json }
requirements:
_format: json
_method: GET
在控制器内部,您可以执行检索变量所需的所有查询,并将这些变量放在视图中:
资源/视图/JsonPrefs/User.json
{
"avatar": "{{ user.avatar }}",
"preferred_color": "{{ user.preferred_color }}"
// ...
}
现在,在您的 JS 中,您将能够通过简单的 AJAX 调用来检索 JSON。出于性能目的,您可以使用 Varnish 缓存 JSON(例如)。这样,您的服务器就不需要在每次读取用户首选项时进行查询。
如果您修改 .htaccess 文件以包含
AddType application/x-httpd-php .js
您可以使用 .js 文件,它将由 PHP 处理,这是您需要的一半。
就该解决方案的丑陋程度而言,我会说这是最不丑陋的机制。您可以尝试通过 PHP 脚本将整个 JS 脚本作为字符串传递,并搜索和替换您需要插入的变量,但我认为您会同意这比您当前使用的解决方案更丑陋。
将所有 .js 文件放在一个文件夹中,并配置您的 HTTP 服务器以将所有对这些文件的请求重定向到一个 PHP 文件,该文件加载文件并输出它们。
假设您有 Apache 并且您的 .js 文件在 /js 中:
RewriteRule /js /getjs.php
获取js.php:
<?php
header('Content-Type: text/javascript');
include_once($_SERVER['SCRIPT_NAME']);
?>
至于避免通过 PHP 解析器运行 .js 文件,除了可能js-variable
通过 AJAX 调用获取 的值外,您几乎无能为力。
您也可以考虑像这样输出值:
var js_variable = <?php echo json_encode ($php_variable); ?>
逃避所有会破坏你的javascript的事情。
至少,您可以使用 PHP 短代码使您的“丑陋”解决方案更简洁:
var js-variable = "<?= $php-variable ?>";