一尘不染

客户端和服务器端编程有什么区别?

javascript

我有这个代码:

<script type="text/javascript">
    var foo = 'bar';
    <?php
        file_put_contents('foo.txt', ' + foo + ');
    ?>

    var baz = <?php echo 42; ?>;
    alert(baz);
</script>

为什么这不将“bar”写入我的文本文件,而是提醒“42”?


注意:此问题的早期修订版明确涉及服务器上的 PHP 和客户端上的 JavaScript。当一种语言在客户端上运行而另一种在服务器上运行时(即使它们是相同的语言),问题和解决方案的本质性质对于任何一对语言都是相同的。当您看到有关特定语言的答案时,请考虑到这一点。


阅读 255

收藏
2021-10-16

共1个答案

一尘不染

您的代码分为两个完全独立的部分,服务器端客户端

                    |
               ---------->
              HTTP request
                    |
+--------------+    |    +--------------+
|              |    |    |              |
|    browser   |    |    |  web  server |
| (JavaScript) |    |    |  (PHP etc.)  |
|              |    |    |              |
+--------------+    |    +--------------+
                    |
  client side       |      server side
                    |
               <----------
          HTML, CSS, JavaScript
                    |

双方通过 HTTP 请求和响应进行通信。PHP 在服务器上执行并输出一些 HTML 和 JavaScript 代码,这些代码作为响应发送到客户端,在客户端解释 HTML 并执行 JavaScript。一旦 PHP 完成输出响应,脚本就会结束,服务器上不会发生任何事情,直到新的 HTTP 请求进来。

示例代码执行如下:

<script type="text/javascript">
    var foo = 'bar';
    <?php
        file_put_contents('foo.txt', ' + foo + ');
    ?>

    var baz = <?php echo 42; ?>;
    alert(baz);
</script>

第 1 步,PHP 执行<?php ?>标签之间的所有代码。结果是这样的:

<script type="text/javascript">
    var foo = 'bar';

    var baz = 42;
    alert(baz);
</script>

file_put_contents呼叫并没有导致任何东西,它只是写了“+富+”到文件中。的<?php echo 42; ?>呼叫导致的输出“42”,这是现在在该代码用来为光斑。

这个生成的 HTML/JavaScript 代码现在被发送到客户端,在那里它被评估。该alert呼叫工作,而foo变量没有任何地方使用。

在客户端甚至开始执行任何 JavaScript 之前,所有 PHP 代码都会在服务器上执行。响应中没有留下 JavaScript 可以与之交互的 PHP 代码。

要调用一些 PHP 代码,客户端必须向服务器发送一个新的 HTTP 请求。这可以使用以下三种可能的方法之一发生:

  1. 一个链接,它使浏览器加载一个新页面。
  2. 表单提交,将数据提交到服务器并加载新页面。
  3. 一个AJAX请求,这是一个JavaScript技术,使一个普通的HTTP请求到服务器(如1和2会),而无需离开当前页面。

这是一个更详细地概述这些方法的问题:

您还可以使用 JavaScript 使浏览器使用window.location或提交表单打开一个新页面,模拟可能性 1. 和 2。

问题说明

首先,让我们了解从我们的服务器提供页面时的事件流:

  • 首先运行 PHP,它生成提供给客户端的 HTML。
  • 然后,HTML 被交付给客户端,在 PHP 完成之后,我想强调的是,一旦代码离开服务器 - PHP 已经完成并且无法再访问它。
  • 然后,带有 JavaScript 的 HTML 到达客户端,客户端可以在该 HTML 上执行 JavaScript。

所以真的,这里要记住的核心是HTTP 是无状态的。一旦请求离开服务器,服务器就不能再接触它。所以,我们的选择是:

  1. 在初始请求完成从客户端发送更多请求。
  2. 对服务器在初始请求中所说的内容进行编码。

解决方案

这是你应该问自己的核心问题是:

我是在写网站还是应用程序?

网站主要是基于页面的,页面加载时间需要尽可能快(例如 - 维基百科)。Web 应用程序更多的是 AJAX,并且执行大量往返以获取客户端快速信息(例如 - 股票仪表板)。

网站

在初始请求完成后从客户端发送更多请求很慢,因为它需要更多具有显着开销的 HTTP 请求。此外,它需要异步性,因为发出 AJAX 请求需要一个处理程序来处理它何时完成。

除非您的站点是从服务器获取该信息的应用程序否则建议再次发出请求。

您需要快速响应时间,这会对转换和加载时间产生巨大影响。在这种情况下,发出 Ajax 请求的初始正常运行时间很慢,而且是不必要的。

你有两种方法来解决这个问题

  • 设置 cookie - cookie 是服务器和客户端都可以读取的 HTTP 请求中发送的标头。
  • 将变量编码为 JSON - JSON 看起来非常接近 JavaScript 对象,并且大多数JSON 对象都是有效的 JavaScript 变量。

设置 cookie真的不是很困难,你只要给它赋值:

setcookie("MyCookie", $value); // Sets the cookie to the value, remember, do not
                               // Set it with HTTP only to true.

然后,您可以使用JavaScript阅读使用document.cookie

这是一个简短的手动解析器,但我在上面链接的答案有更好的测试:

var cookies = document.cookie.split(";").
    map(function(el){ return el.split("="); }).
    reduce(function(prev,cur){ prev[cur[0]] = cur[1]; return prev },{});
alert(cookies["MyCookie"]); // Value set with PHP.

Cookies 适用于少量数据。这就是跟踪服务经常做的事情。

一旦我们有更多数据,我们可以在 JavaScript 变量中使用 JSON 对其进行编码:

<script>
    var myServerData = <?=json_encode($value)?>; // Don't forget to sanitize
                                                 //server data
</script>

假设$valuejson_encode能够在PHP端(通常是这样)。这种技术就是 Stack Overflow 对其聊天所做的事情(仅使用 .NET 而不是 PHP)。

应用

如果您正在编写应用程序 - 突然之间,初始加载时间并不总是与应用程序的持续性能一样重要,并且开始分别加载数据和代码是值得的。

我在这里的回答解释了如何在 JavaScript 中使用 AJAX 加载数据:

function callback(data){
    // What do I do with the response?
}

var httpRequest = new XMLHttpRequest;
httpRequest.onreadystatechange = function(){
    if (httpRequest.readyState === 4) { // Request is done
        if (httpRequest.status === 200) { // successfully
            callback(httpRequest.responseText); // We're calling our method
        }
    }
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();

或者使用 jQuery:

$.get("/your/url").done(function(data){
    // What do I do with the data?
});

现在,服务器只需要包含一个/your/url路由/文件,其中包含获取数据并对其进行处理的代码,在您的情况下:

<?php
$val = myService->getValue(); // Makes an API and database call
header("Content-Type: application/json"); // Advise client of response type
echo json_encode($val); // Write it to the output

这样,我们的 JavaScript 文件会要求数据并显示它,而不是要求代码或布局。这更干净,并且随着应用程序变得更高而开始得到回报。它也是更好的关注点分离,它允许在不涉及任何服务器端技术的情况下测试客户端代码,这是另一个优点。

2021-10-16