Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
SP指令是指:用于設置JSP頁面相關屬性的一個語法命令,例如:設置頁面編碼字符集、導入其他包等等。JSP中提供了三個指令,分別是:page指令、include指令、taglib指令。其中page指令用于設置JSP頁面屬性,include指令用于引入其他的JSP文件,taglib指令用于引入標簽庫。這一小節內容介紹include指令的使用。
include指令作用:將指定的文件引入到當前JSP頁面里面。include指令會將引入的文件內容嵌入到當前JSP頁面中的對應位置。
<%@ include file="文件的相對路徑" %>
案例代碼:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>這是HTML頭部</title>
</head>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 引入頭部文件 --%>
<%@ include file="header.jsp" %>
<body>
<div style="background-color: cadetblue">
這是正文內容區域
</div>
<%-- 引入底部文件 --%>
<%@ include file="footer.html" %>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div style="background-color: antiquewhite;">
這是footer底部內容區域
</div>
啟動Tomcat容器,瀏覽器訪問http://localhost:8080/servlet/include.jsp,結果如下:
include指令的本質是什么呢???我們來查看下編譯之后的Java源代碼,找到上面include.jsp文件編譯之后的源文件,如下所示:
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.98
* Generated at: 2024-02-25 05:06:41 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package com.gitcode.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class include_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
static {
_jspx_dependants = new java.util.HashMap<java.lang.String,java.lang.Long>(2);
_jspx_dependants.put("/footer.jsp", Long.valueOf(1708837593266L));
_jspx_dependants.put("/header.jsp", Long.valueOf(1708837593271L));
}
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>這是HTML頭部</title>\r\n");
out.write("</head>");
out.write("\r\n");
out.write("<body>\r\n");
out.write("\r\n");
out.write("<div style=\"background-color: cadetblue\">\r\n");
out.write(" 這是正文內容區域\r\n");
out.write("</div>\r\n");
out.write("\r\n");
out.write('\r');
out.write('\n');
out.write("\r\n");
out.write("<div style=\"background-color: antiquewhite;\">\r\n");
out.write(" 這是footer底部內容區域\r\n");
out.write("</div>");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
通過上面源代碼,可以看到,使用include指令引入的兩個文件,最終都會將兩個文件中的內容直接嵌入到當前include.jsp文件里面,如下所示:
所以include指令的本質就是將引入文件中的內容,直接拼接到當前JSP頁面的對應位置。這里也就會存在一個問題,引入的JSP文件中,不能存在和當前JSP頁面相同的變量名稱,因為變量名稱相同會導致編譯失敗。另外,使用include指令引入其他的JSP文件時候,只會生成訪問的那個JSP文件的源代碼,被引入的JSP文件不會生成對應的源代碼。
以上,就是include指令的使用及其本質。
今天就到這里,未完待續~~
PHP中有兩個引入文件的語言結構:include、require
1、注意這兩個都是語言結構不是方法,與echo、print、isset()、empty()、unset()等類似都是語言結構不是函數!!!!!
2、include與require都是引入外部文件到當前上下文環境,但是他們有一些區別:
一、被包含文件先按參數給出的路徑尋找,如果沒有給出目錄(只有文件名)時則按照 include_path 指定的目錄尋找。如果在 include_path 下沒找到該文件則 include 最后才在調用腳本文件所在的目錄和當前工作目錄下尋找。如果最后仍未找到文件則 include 結構會發出一條警告;這一點和 require 不同,后者會發出一個致命錯誤。(在這點上include_once與require_once類似,但是他們在導入一個已導入的文件都會忽略,但是他們在引入文件時會判斷是否引入會降低性能)
二、關于引入的文件:當一個文件被包含時,其中所包含的代碼繼承了 include、require 所在行的變量范圍。從該處開始,調用文件在該行處可用的任何變量在被調用的文件中也都可用。不過所有在包含文件中定義的函數和類都具有全局作用域。
EG1:
vars.php
<?php
$color = 'green';
$fruit = 'apple';
?>
test.php
<?php
echo "A $color $fruit"; // A
include 'vars.php';
echo "A $color $fruit"; // A green apple
?>
如果 include 出現于調用文件中的一個函數里,則被調用的文件中所包含的所有代碼將表現得如同它們是在該函數內部定義的一樣。所以它將遵循該函數的變量范圍。此規則的一個例外是魔術常量,它們是在發生包含之前就已被解析器處理的。
3、include返回值:
處理返回值:在失敗時 include 返回 FALSE 并且發出警告。成功的包含則返回 1,除非在包含文件中另外給出了返回值。可以在被包括的文件中使用 return 語句來終止該文件中程序的執行并返回調用它的腳本。同樣也可以從被包含的文件中返回值。可以像普通函數一樣獲得 include 調用的返回值。不過這在包含遠程文件時卻不行,除非遠程文件的輸出具有合法的 PHP 開始和結束標記(如同任何本地文件一樣)。可以在標記內定義所需的變量,該變量在文件被包含的位置之后就可用了。因為 include 是一個特殊的語言結構,其參數不需要括號。在比較其返回值時要注意。
EG2:
<?php
// won't work, evaluated as include(('vars.php') == TRUE), i.e. include('')
if (include('vars.php') == TRUE) {
echo 'OK';
}
// works
if ((include 'vars.php') == TRUE) {
echo 'OK';
}
講解:
$bar 的值為 1 是因為 include 成功運行了。注意以上例子中的區別。第一個在被包含的文件中用了 return 而另一個沒有。如果文件不能被包含,則返回 FALSE 并發出一個 E_WARNING 警告。如果在包含文件中定義有函數,這些函數不管是在 return 之前還是之后定義的,都可以獨立在主文件中使用。如果文件被包含兩次,PHP 5 發出致命錯誤因為函數已經被定義,但是 PHP 4 不會對在 return 之后定義的函數報錯。推薦用 include_once 而不是檢查文件是否已包含并在包含文件中有條件返回.
3、include引入文件的處理:(這點很重要)
當一個文件被包含時,語法解析器在目標文件的開頭脫離 PHP 模式并進入 HTML 模式,到文件結尾處恢復。由于此原因,目標文件中需要作為 PHP 代碼執行的任何代碼都必須被包括在有效的 PHP 起始和結束標記之中。并且當執行完成之后直接加入到緩沖區,將被導入的文件中的變量加入到當前的作用域變量鏈上。
EG3:
//t1.php 文件內容
1234<?php $name="PQS"; ?>5678<?php return 1; ?>9
//t2.php文件內容
<?php
include "t1.php";
echo $name;
//開始執行t2.php
會輸出:12345678PQS
案例解析:
首先當include "t1.php";文件時PHP解析器脫離PHP模式進入HTML模式開始解析,因為HTML模式是將內容直接加入到緩沖區,所以沒有標簽1234會被首先加入到緩沖區,然后在執行<?php $name="PQS"; ?>這里就會把$name這個變量加入到t2.php的include "t1.php"這句代碼的上線文變量作用域中。然后接著在回到HTM模式將5678加入到緩沖區,接下來遇到<?php return 1;?>就開始進入PHP模式進行執行代碼,因為include是接受return的,所以當這里return 1之后整個文件的加載就到此處結束了, 返回到t2的代碼執行域中了,這也是為什么最后沒有輸出9的原因。
舉個例子證明PHP將文件輸入到緩沖區:
//t3.php
1234567
//t4.php
<?php
$string = get_include_contents('t3.php');
function get_include_contents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
echo $string;
//執行t4.php
1234567
案例分析:
函數get_include_contents($filename)
在include之前開啟緩沖區,當include將t3.php文件引入后就使用ob_get_contents()方法獲取緩沖區數據賦值給$contents,然后使用ob_end_clean將緩沖區數據丟棄最后將$contents返回,最后輸出返回值就是t3.php在經過php運行的值。
4、include支持引入URL:
如果“URL include wrappers”在 PHP 中被激活,可以用 URL(通過 HTTP 或者其它支持的封裝協議——見支持的協議和封裝協議)而不是本地文件來指定要被包含的文件。如果目標服務器將目標文件作為 PHP 代碼解釋,則可以用適用于 HTTP GET 的 URL 請求字符串來向被包括的文件傳遞變量。嚴格的說這和包含一個文件并繼承父文件的變量空間并不是一回事;該腳本文件實際上已經在遠程服務器上運行了,而本地腳本則包括了其結果。
<?php
/* This example assumes that www.example.com is configured to parse .php *
* files and not .txt files. Also, 'Works' here means that the variables *
* $foo and $bar are available within the included file. */
// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';
// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';
// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';
$foo = 1;
$bar = 2;
include 'file.txt'; // Works.
include 'file.php'; // Works.
此案例是PHP官網案例,如果不懂之處請移步值PHP官網include章節!
var aedes = new aedes_1.default();
^
TypeError: aedes_1.default is not a constructor
Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use node --trace-warnings ... to show where the warning was created)
/Users/jiechengyang/src/node-app/mqtt-examples/dist/01/mqtt-server.js:1
import Aedes from 'aedes';
^^^^^^
SyntaxError: Cannot use import statement outside a module
import Aedes from 'aedes'
import { createServer } from 'net'
const port = 1883
const aedes = new Aedes()
const server = createServer(aedes.handle)
server.listen(port, function () {
console.log('server started and listening on port ', port)
})
import Aedes, { AedesOptions } from './types/instance'
export declare function createBroker(options?: AedesOptions): Aedes
export * from './types/instance'
export * from './types/packet'
export * from './types/client'
export { default } from './types/instance'
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"esModuleInterop": true,
"strict": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"esModuleInterop": true,
"strict": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
因為是初學ts,造成上面的問題的原因是:個人使用的編譯選項不對導致,因此,應該熟悉tsconfig.json 的編譯參數.最后的tsconfig.json配置如下:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"lib": [
"DOM",
"ES2022"
],
"module": "ES2022",
"moduleResolution":"node",
// "outDir": "dist",
"rootDir": "src",
"sourceMap": true,
"strict": true,
"target": "ES2022"
},
"include": [
"src/**/*.ts"
]
}
報錯信息表明您的 JavaScript 文件被 Node.js 解釋為 ECMAScript 模塊(ES module),而不是 CommonJS 模塊。這通常是因為文件擴展名是 .mjs,或者因為 type: module 被設置在了 package.json 文件中。
在您的情況下,看起來您正在使用 import 語句導入模塊,這是 ECMAScript 模塊的語法。然而,默認情況下,Node.js 將文件當作 CommonJS 模塊處理。
為了解決這個問題,有幾個選項:
將文件擴展名更改為 .mjs:
將您的文件擴展名從 .js 更改為 .mjs。這會告訴 Node.js 將文件視為 ECMAScript 模塊。
將 type 設置為 module:
在您的 package.json 文件中,可以添加 "type": "module",以將所有 .js 文件視為 ECMAScript 模塊。
{
"type": "module",
"scripts": {
"start": "node your-script.js"
}
}
注意:將 "type": "module" 添加到 package.json 可能會影響到項目中其他依賴的模塊。這是因為 CommonJS 和 ECMAScript 模塊有一些不同之處。確保您的項目及其依賴項對 ECMAScript 模塊提供了正確的支持。
當配置 TypeScript 編譯器選項時,各個屬性有著不同的作用。以下是您 tsconfig.json 文件中使用的一些關鍵屬性的解釋:
選擇使用 CommonJS 還是 ECMAScript 模塊(ES module)通常取決于您的項目的特定要求和部署環境。下面是一些建議:
使用 CommonJS:
Node.js 項目: 如果您的項目是一個 Node.js 項目,特別是在舊版 Node.js 中,使用 CommonJS 是很自然的選擇。Node.js 長期以來一直使用 CommonJS 模塊系統。
現有項目: 如果您的項目中已經使用了 CommonJS,為了保持一致性,可能更容易繼續使用 CommonJS。
npm 生態系統: 大多數 Node.js 包都是以 CommonJS 格式發布的,因此在使用 npm 生態系統中,使用 CommonJS 通常更為方便。
使用 ECMAScript 模塊:
前端項目: 在瀏覽器環境或支持 ES module 的環境中,可以考慮使用 ECMAScript 模塊。現代前端開發中,許多工具和框架都支持 ES module。
靜態分析和優化: ECMAScript 模塊在靜態分析和優化方面具有一些優勢,因為它們提供了更多的信息,這有助于一些工具進行更好的代碼優化。
模塊化加載器: 如果您的項目中使用了模塊加載器(如Webpack、Rollup等),這些工具通常支持 ES module,并且可以更好地進行代碼分割和懶加載等優化。
組合使用:
在某些場景下,您也可以在同一項目中同時使用 CommonJS 和 ES module,這種混合使用的方式在過渡期或特定的工作流中可能會有用。例如,在一些前端項目中,可以使用 Babel 或 Webpack 進行模塊的轉換,將 CommonJS 轉換為 ES module 以獲得一些優勢。
總體而言,選擇 CommonJS 還是 ES module 取決于您項目的具體需求、使用的環境以及團隊的偏好。在許多情況下,Node.js 項目會繼續使用 CommonJS,而前端項目則更傾向于使用 ES module。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。