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
域請(qǐng)求:
現(xiàn)代的所有的瀏覽器都遵守同源策略,所謂的源指的就是一個(gè)域名、一個(gè)服務(wù)器,同源是指兩個(gè)腳本擁有相同的域名,不同源指的是不同的域名,同源策略指的是,一個(gè)源的腳本不能讀取或操作其他源的http響應(yīng)和cookie,也就是出于安全方面的考慮,頁(yè)面中的JavaScript無法訪問其他服務(wù)器上的數(shù)據(jù),這就是所謂的“同源策略”。
同源是指協(xié)議、域名和端口都一致。
不同源限制的內(nèi)容:
跨域請(qǐng)求時(shí),不同域的服務(wù)器是返回了數(shù)據(jù)的,只不過瀏覽器攔截了響應(yīng)數(shù)據(jù);同時(shí)也說明了跨域并不能完全阻止CSRF,因?yàn)檎?qǐng)求畢竟是發(fā)出去了;
CORS(Cross-Origin Response Sharing)跨域資源共享:
通過XHR實(shí)現(xiàn)Ajax通信的主要限制,是跨域安全策略;默認(rèn)情況下,只能訪問同一個(gè)域中的資源,這種安全策略可以預(yù)防某些惡意行為,如:
var xhr = new XMLHttpRequest();
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.open("GET", "https://www.zeronetwork.cn/study/index.html");
xhr.send(null);
其拋出了CORS policy異常;
XHR2規(guī)范了在通過HTTP響應(yīng)中如何選擇合適的CORS(Cross-Origin Response Sharing,跨域資源共享)去跨域訪問資源;其定義了在必須訪問跨源資源時(shí),瀏覽器與服務(wù)器應(yīng)該如何溝通;CORS的基本思想是,就是使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進(jìn)行溝通,從面決定請(qǐng)求或響應(yīng)是否應(yīng)該成功;
比如一個(gè)簡(jiǎn)單的使用GET或POST發(fā)送的請(qǐng)求,默認(rèn)情況下它沒有自定義的頭,但一般會(huì)包括一個(gè)Origin請(qǐng)求頭,其中包含請(qǐng)求頁(yè)面的源信息(協(xié)議、域名和端口),以便服務(wù)器根據(jù)這個(gè)頭部信息來決定是否給予響應(yīng),如Origin頭部示例:
Origin: https://www.zeronetwork.cn
如果服務(wù)器認(rèn)為這個(gè)請(qǐng)求可以接受,就在響應(yīng)的Access-Control-Allow-Origin([??la?])頭中回發(fā)相同的源信息(如果是公共資源,可以回發(fā)”*”),例如:
Access-Control-Allow-Origin: https://www.zeronetwork.cn
如果沒有這個(gè)響應(yīng)頭,或者有這個(gè)響應(yīng)頭但與請(qǐng)求Origin頭信息不匹配,瀏覽器就會(huì)駁回請(qǐng)求;反之,瀏覽器會(huì)處理請(qǐng)求;
實(shí)現(xiàn)跨域:
IE和標(biāo)準(zhǔn)瀏覽器已經(jīng)實(shí)現(xiàn)了各自的跨域解決方案;
標(biāo)準(zhǔn)瀏覽器對(duì)CORS的實(shí)現(xiàn):
在標(biāo)準(zhǔn)瀏覽器中,客戶端在使用Ajax跨域請(qǐng)求時(shí),拋出異常,不能訪問;如:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
}
xhr.open("GET","https://www.b.com/normal/example.json");
xhr.send(null);
被請(qǐng)求的服務(wù)端需要設(shè)置Access-Control-Allow-Origin響應(yīng)頭,以便于瀏覽器識(shí)別它是否為可信源。
例如,在Apache服務(wù)器中,在服務(wù)器的配置中添加如下設(shè)置:
Header set Access-Control-Allow-Origin 'origin-list'
對(duì)于Nginx,設(shè)置此http頭的命令是:
add_header 'Access-Control-Allow-Origin' 'origin-list'
或者使用.htaccess文件配置,如:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
order allow,deny
allow from all
應(yīng)用:
xhr.open("GET","https://www.b.com/cors/example.json");
單獨(dú)為某個(gè)后端程序設(shè)置響應(yīng)頭,例如b.com/cors.php:
<?php
header("Access-Control-Allow-Origin: *");
echo "跨域訪問b.com/cors.php";
無論同源請(qǐng)求還是跨源請(qǐng)求都使用相同的接口,因此對(duì)地本地資源,最好使用相對(duì)URL,在訪問遠(yuǎn)程資源時(shí)再使用絕對(duì)URL;這樣做能消除歧義,避免出現(xiàn)限制訪問頭部或本地cookie信息等問題。
IE對(duì)CORS的實(shí)現(xiàn):
微軟在IE8中引入了XDR(XDomainRequest)對(duì)象,其與XHR類似,其可直接用于發(fā)起安全的跨域請(qǐng)求,實(shí)現(xiàn)安全可靠的跨域通信;
var xdr = new XDomainRequest();
console.log(xdr);
IE11和標(biāo)準(zhǔn)瀏覽器并不支持;
XDR對(duì)象的使用方法與XHR對(duì)象非常相似,兩者擁有幾乎相同的屬性和方法,也是調(diào)用open()方法,再調(diào)用send()方法;但與XHR對(duì)象的open()方法不同,XDR對(duì)象的open()方法只接收兩個(gè)參數(shù):請(qǐng)求的類型和URL;如:
var xdr = new XDomainRequest();
console.log(xdr);
// xdr.open("GET", "http://www.c.com/nocors.php");
xdr.open("GET", "example.php");
xdr.onload = function(){
console.log(xdr.responseText);
}
xdr.send();
此時(shí),不管是跨域的還是同源的都不允許訪問,拋出“在 Access-Control-Allow-Origin 標(biāo)頭中未找到源”;
XDR對(duì)象的安全機(jī)制中部分實(shí)現(xiàn)了CORS,后端也需要設(shè)置 Access-Control-Allow-Origin響應(yīng)頭,如c.com/cors.php:
<?php
header("Access-Control-Allow-Origin: *");
echo "設(shè)置了ACAO響應(yīng)頭";
請(qǐng)求端:
xdr.open("GET", "http://www.c.com/cors.php");
XDR對(duì)象屬性和事件:
請(qǐng)求返回后,會(huì)觸發(fā)onload事件,響應(yīng)的數(shù)據(jù)也會(huì)保存在responseText屬性中,響應(yīng)的MIME類型保存在contentType屬性中,如:
var xdr = new XDomainRequest();
xdr.onload = function(){
console.log(xdr.contentType); // application/json
console.log(xdr.responseText);
}
xdr.open("post","http://www.c.com/cors/example.json");
xdr.send(null);
例如再請(qǐng)求一個(gè)同源的contentType.php:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
echo '{"username":"王唯","age":18,"sex":true}';
在接收到響應(yīng)后,只能訪問響應(yīng)的原始文本,不能確定響應(yīng)的狀態(tài)代碼(也就是它沒有status屬性);而且,只要響應(yīng)有效就會(huì)觸發(fā)onload事件,如果失敗就會(huì)觸發(fā)error事件,但除了錯(cuò)誤本身之外,沒有其他信息可以確定請(qǐng)求是否成功,所以唯一能夠確定的就只有請(qǐng)求未成功;
要檢測(cè)錯(cuò)誤,如要指定error事件處理程序,如:
xdr.onerror = function(){
console.log("出現(xiàn)錯(cuò)誤");
}
由于導(dǎo)致XDR請(qǐng)求失敗的因素很多,因此,最好通過error事件處理程序來捕獲該事件,否則,即使請(qǐng)求失敗也不會(huì)有任何提示。
在請(qǐng)求返回前調(diào)用abort()方法可以終止請(qǐng)求,如:
xdr.abort();
與XHR對(duì)象一樣,XDR也支持timout屬性和ontimeout事件,如:
xdr.timeout=1000;
xdr.ontimeout = function(){
console.log("請(qǐng)求超過1秒");
};
onprogress事件:
應(yīng)該始終定義 xdr.onprogress 事件,即使它是一個(gè)空函數(shù),否則 XDomainRequest 對(duì)于重復(fù)請(qǐng)求,可能不會(huì)觸發(fā) onload 事件;
xdr.onprogress = function(event){
console.log(event);
};
XDR與XHR的不同之外:
1、必須使用 HTTP 或 HTTPS 協(xié)議訪問目標(biāo) URL:
因?yàn)閄DR對(duì)象依賴于一個(gè)HTTP響應(yīng)頭來實(shí)現(xiàn)訪問控制,所以它要求目標(biāo)URL符合HTTP或HTTPS 協(xié)議,以便于XDR對(duì)象檢驗(yàn)響應(yīng)頭;
2、只支持GET和POST請(qǐng)求;
3、不能設(shè)置自定義請(qǐng)求頭信息,也不能訪問響應(yīng)頭部信息;
4、只支持text/plain作為請(qǐng)求頭Content-Type的取值:在XDR中,不管是GET還是POST請(qǐng)求,Content-Type被限制成“text/plain”,所以服務(wù)端不會(huì)把請(qǐng)求主體數(shù)據(jù)解析成鍵值對(duì),即不能從參數(shù)中獲取到POST的數(shù)據(jù),只能讀取流數(shù)據(jù),需要其自行解析,如:
var xdr = new XDomainRequest();
xdr.open("POST", "xdrpost.php");
xdr.onload = function(){
console.log(xdr.responseText);
};
var param = "username=wangwei&age=18";
xdr.send(param);
xdrpost.php:
<?php
header("Access-Control-Allow-Origin: *");
$content = file_get_contents("php://input");
// echo $content; // username=王 唯&age=18
$arr = explode("&", $content);
foreach ($arr as $value) {
$v = explode("=", $value);
echo "key:$v[0], value:$v[1] \r\n";
}
5、身份驗(yàn)證和cookie不能和請(qǐng)求一起發(fā)送,也不會(huì)隨響應(yīng)返回;
6、請(qǐng)求的URL必須和被請(qǐng)求的URL采用相同的協(xié)議:兩者的協(xié)議必須統(tǒng)一,要么是HTTP,要么是HTTPS;
7、所有XDR請(qǐng)求都是異步執(zhí)行的,不能用它來創(chuàng)建同步請(qǐng)求;
Preflighted Requests:
CORS通過一種叫做Prelighted Requests的透明服務(wù)器驗(yàn)證機(jī)制支持開發(fā)人員使用自定義的頭部、GET或POST之外的請(qǐng)求方式,以及不同類型的主體內(nèi)容;
在使用下列高級(jí)選項(xiàng)來發(fā)送請(qǐng)求時(shí),就會(huì)向服務(wù)器發(fā)送一個(gè)Preflight請(qǐng)求,這種請(qǐng)求使用OPTIONS方式,發(fā)送下列頭部:
以下是一個(gè)帶有自定義頭部customHeader,并使用POST方法發(fā)送的數(shù)據(jù),如:
發(fā)送這個(gè)請(qǐng)求后,服務(wù)器端可以決定是否允許這種類型的請(qǐng)求,其通過在響應(yīng)中發(fā)送如下頭部與瀏覽器進(jìn)行溝通:
例如,允許任何源、POST請(qǐng)求方式、自定義頭customHeader以及請(qǐng)求的緩存時(shí)間:
如:
var xhr = new XMLHttpRequest();
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.open("OPTIONS","https://www.b.com/flighted.php",true);
xhr.setRequestHeader("customHeader", "customValue");
xhr.send(null);
后端flighted.php:
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Max-Age: 1728000");
echo "有Headers、Methods頭信息";
Preflight請(qǐng)求結(jié)束后,結(jié)果將按照響應(yīng)中指定的時(shí)間緩存起來;
帶憑據(jù)的請(qǐng)求:
默認(rèn)情況下,跨域請(qǐng)求不提供憑據(jù)(cookie、HTTP認(rèn)證及客戶端SSL證明等);
通過將XHR對(duì)象的withCredentials屬性設(shè)置為true,可以指定某個(gè)跨域請(qǐng)求應(yīng)該發(fā)送憑據(jù)(授權(quán)信息);如:
xhr.withCredentials = true;
xhr.send(null);
當(dāng)使用帶有憑據(jù)的請(qǐng)求時(shí),不能把Access-Control-Allow-Origin設(shè)為*,并且Access-Control-Allow-Origin只能設(shè)置一個(gè)域,不能是多個(gè),否則會(huì)拋出異常;
后端c.com/credentials.php:
header("Access-Control-Allow-Origin: http://www.a.com");
echo "c.com/example.php,已經(jīng)設(shè)置了ACAO";
如果服務(wù)端接受帶憑據(jù)的請(qǐng)求,必須設(shè)置Access-Control-Allow-Credentials: true響應(yīng)頭;
如后端c.com/ credentials.php:
header("Access-Control-Allow-Origin: http://www.a.com");
header("Access-Control-Allow-Credentials: true");
echo "設(shè)置了Origin,也設(shè)置了Credentials";
echo json_encode($_COOKIE);
如果在同源下配置withCredentials,無論配置true還是false,效果都會(huì)相同,且會(huì)一直提供憑據(jù)信息;另外,同時(shí)還可以發(fā)送自定義請(qǐng)求頭,如后端credentials.php:
<?php
header("Access-Control-Allow-Origin: http://www.a.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: customHeader");
echo "設(shè)置了Origin,也設(shè)置了Credentials";
echo json_encode($_COOKIE);
服務(wù)端還可以在Preflight響應(yīng)中發(fā)送這個(gè)HTTP頭部,但不能把Access-Control-Allow-Headers設(shè)為*;
跨瀏覽器的CORS:
即使瀏覽器對(duì)CORS的支持程度并不一致,但所有瀏覽器都支持簡(jiǎn)單的請(qǐng)求(非Preflight和不帶憑據(jù)的請(qǐng)求),因此有必要實(shí)現(xiàn)一個(gè)跨瀏覽器的方案:檢測(cè)XHR是否支持CORS的最簡(jiǎn)單方式,就是檢查是否存在withCredentials屬性,再結(jié)合檢測(cè)XDomainRequest對(duì)象是否存在,就可以兼顧所有瀏覽器了,如:
function createCORSRequest(method, url, withCredentials){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url);
xhr.withCredentials = withCredentials;
}else if(typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
}else{
xhr = null;
}
return xhr;
}
var request = createCORSRequest("GET", "https://www.b.com/credentials.php", true);
if(request){
request.onload = function(){
console.log(request.responseText);
};
request.send(null);
}
示例:使用HEAD和CORS請(qǐng)求鏈接的詳細(xì)信息,如:
var supportsCORS = (new XMLHttpRequest).withCredentials != undefined;
var links = document.getElementsByTagName("a");
for(var i=0; i<links.length; i++){
var link = links[i];
if(!link.href) continue;
if(link.title) continue;
if(link.host !== location.host || link.protocol != location.protocol){
link.title = "站外鏈接";
if(!supportsCORS) continue;
}
if(link.addEventListener)
link.addEventListener("mouseover", mouseoverHandler, false);
else
link.attachEvent("onmouseover", mouseoverHandler);
}
function mouseoverHandler(e){
var link = e.target || e.srcElement;
var url = link.href;
var xhr = new XMLHttpRequest();
xhr.open("HEAD", url);
xhr.onreadystatechange = function(){
if(xhr.readyState !== 4) return;
if(xhr.status == 200){
var type = xhr.getResponseHeader("Content-Type");
var size = xhr.getResponseHeader("Content-Length");
var date = xhr.getResponseHeader("Last-Modified");
link.title = "類型:" + type + "\n" +
"大小:" + size + "\n" +
"時(shí)間:" + date;
}else{
if(!link.title)
link.title = "獲取不到詳細(xì)信息:\n" +
xhr.status + " " + xhr.statusText;
}
};
xhr.send(null);
if(link.removeEventListener)
link.removeEventListener("mouseover", mouseoverHandler, false);
else
link.detachEvent("onmouseover", mouseoverHandler);
}
HTML:
<a href="https://www.zeronetwork.cn/edu/">edu</a>
<a href="https://www.zeronetwork.cn/study/">study</a>
<a href="http://www.a.com/ demo.html">a.com</a>
<a>no href</a>
<a href="https://www.apple.com" title="baidu">apple.com</a>
<a href="https://cn.bing.com">bing</a>
其它跨域技術(shù):
雖然CORS技術(shù)已經(jīng)無處不在,但在CORS出現(xiàn)之前,就已經(jīng)存在一些跨域的技術(shù)了,雖然這些技術(shù)應(yīng)用起來有些麻煩,但它們絕大部分不需要修改服務(wù)器端代碼,所以直到現(xiàn)在這些技術(shù)仍然被廣泛使用;
后端代理方式:
這種方式可以解決所有跨域問題,也就是將本域的后端程序作為代理,每次對(duì)其它域的請(qǐng)求都轉(zhuǎn)交給該代理程序,其通過模擬http請(qǐng)求去訪問其它域,再將返回的結(jié)果返回給前端,這樣做的好處是,無論訪問的是文檔、還是JS文件都可以實(shí)現(xiàn)跨域;
例如,b.com/data.php響應(yīng)JSON字符串:
<?php
$json_str = '{"name":"wagwei","sex":true,"age":18}';
echo $json_str;
a.com/getdata.php服務(wù)端獲取b.com/data.php響應(yīng):
<?php
// 創(chuàng)建cURL資源
$ch = curl_init();
// 設(shè)置URL和相應(yīng)的選項(xiàng)
curl_setopt($ch, CURLOPT_URL, "http://www.b.com/data.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
// 抓取URL并把它傳遞給瀏覽器
curl_exec($ch);
// 關(guān)閉cURL資源,并釋放系統(tǒng)資源
curl_close($ch);
a.com/data.html使用Ajax請(qǐng)求同源的getdata.php:
var xhr = new XMLHttpRequest();
xhr.open("GET", "getdata.php");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
};
xhr.send(null);
基于iframe實(shí)現(xiàn)跨域:
基于iframe實(shí)現(xiàn)的跨域要求兩個(gè)域?qū)儆谕粋€(gè)根域,如:www.a.com和b.a.com其使用同一協(xié)議(例如都是 http)和同一端口(例如都是80),此時(shí)在兩個(gè)頁(yè)面中同時(shí)設(shè)置document.domain為同一個(gè)主域,就實(shí)現(xiàn)了同域,從而可以實(shí)現(xiàn)通信;如b.a.com中的iframe.html:
<h1>iframe</h1>
<img src="images/hu.png" />
<script>
document.domain = "a.com";
function show(msg){
alert("收到的:" + msg);
}
if(parent.parentFun){
parent.parentFun();
}
</script>
www.a.com主頁(yè)面為:
<script>
function parentFun(){
alert("parentFun");
}
</script>
<iframe src="http://b.a.com/iframe.html" id="myframe"></iframe>
<script>
var myframe = document.getElementById("myframe");
document.domain = "a.com";
myframe.onload = function(){
var win = myframe.contentWindow;
console.log(win);
win.show("零點(diǎn)程序員");
var doc = myframe.contentDocument;
console.log(doc);
}
</script>
使用window.name和iframe進(jìn)行跨域:
window的name屬性返回的是該window的名稱,它的值有個(gè)特點(diǎn):在不同的頁(yè)面(甚至不同域名)加載后依舊存在,并且可以支持非常長(zhǎng)的name值(2MB),即在一個(gè)窗口(window)的生命周期內(nèi),窗口載入的所有的頁(yè)面都是共享一個(gè)window.name,每個(gè)頁(yè)面對(duì)window.name都有讀寫的權(quán)限;
正因?yàn)閣indow的name屬性的這個(gè)特征,所以可以使用window.name來進(jìn)行跨域;例如a.html:
<h1>a.html</h1>
<script>
window.name = "頁(yè)面a設(shè)置的name值";
setTimeout(function(){
window.location = "b.html";
},3000); // 3秒后在當(dāng)前window中載入新的頁(yè)面
</script>
b.html:
<h1>b.html</h1>
<script>
alert(window.name); // 頁(yè)面a設(shè)置的name值
</script>
跨域:例如,有一個(gè)a.com/a.html頁(yè)面,需要通過js來獲取位于另一個(gè)不同域上的頁(yè)面,如:b.com/b.html里的數(shù)據(jù):
<script>
window.name = "b.com/b.html中的數(shù)據(jù)";
</script>
如果b.html不跳轉(zhuǎn),其他頁(yè)也可以獲取數(shù)據(jù),可以采用iframe;
如a.com/a.html:
<h1>a.html</h1>
<iframe id="iframe" src="http://www.b.com/b.html" style="display:none"></iframe>
<script>
var iframe = document.getElementById("iframe");
// iframe在一開始載入b.com/b.html會(huì)執(zhí)行此函數(shù)
iframe.onload = function(){
// 當(dāng)iframe.src為b.html時(shí)觸發(fā),此時(shí)iframe和當(dāng)前頁(yè)面已經(jīng)同源,可以訪問
iframe.onload = function(){
var data = iframe.contentWindow.name;
alert(data);
};
// 這里的b.html為隨便一個(gè)頁(yè)面,只要與當(dāng)前頁(yè)面同源就可以,
// 目錄是讓iframe與當(dāng)前頁(yè)面同源
iframe.src = "b.html";
}
</script>
使用location.hash+iframe跨域:
假設(shè)a.com/a.html要向b.com/b.html傳遞信息;如a.com/a.html:
<h1>a.html</h1>
<script>
function checkHash(){
try{
var data = location.hash ? location.hash.substring(1) : '';
console.log("收到的數(shù)據(jù)是:" + data);
}catch(e){}
}
setInterval(checkHash, 5000);
window.onload = function(){
var iframe = document.createElement("iframe");
// iframe.style.display = "none";
iframe.src = "http://www.b.com/b.html#param"; // 傳遞的location.hash
document.body.appendChild(iframe);
};
</script>
b.com/b.html:
<h1>b.html</h1>
<script>
function checkHash(){
var data = "";
// 模擬一個(gè)簡(jiǎn)單的參數(shù)處理操作
switch(location.hash){
case "#param":
data = "somedata";
break;
case "#other":
// ...
break;
default:
break;
}
data && callBack("#" + data);
}
function callBack(hash){
// ie、chrome的安全機(jī)制無法修改parent.location.hash
//所以要利用一個(gè)中間的www.csdnblogs.com域下的代理iframe
var proxy = document.createElement("iframe");
proxy.style.display = "none";
proxy.src = "http://www.a.com/c.html" + hash;
// 注意該文件在a.com中
document.body.appendChild(proxy);
}
window.onload = checkHash;
</script>
a.com/c.html:
<script>
//因?yàn)閜arent.parent和自身屬于同一個(gè)域,所以可以改變其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
</script>
圖像Ping:
使用<img>標(biāo)簽,也可以動(dòng)態(tài)創(chuàng)建圖像,使用它們的onload和onerror事件處理程序來確定是否接收到了響應(yīng);例如:
var img = new Image();
img.onload = img.onerror = function(){
console.log("Done");
};
img.src = "https://www.zeronetwork.cn/study/pingimg.php?name=wangwei";
pingimg.php:
if($_GET['name']){
echo $_GET['name'];
}
圖像Ping有兩個(gè)主要的缺點(diǎn),一是只能發(fā)送GET請(qǐng)求,二是無法訪問服務(wù)器的響應(yīng)文本,因此,圖像Ping只能用于瀏覽器與服務(wù)器間的單向通信;提交的數(shù)據(jù)是通過查詢字符串形式發(fā)送的,但響應(yīng)可以是任意內(nèi)容,但通常是像素圖或204響應(yīng);
通過圖像Ping,瀏覽器得不到任何具體的數(shù)據(jù),但通過偵聽load和error事件,它能知道響應(yīng)是什么時(shí)候接收到的,此時(shí)可以實(shí)現(xiàn)一些自身的邏輯;
示例:圖像Ping最常用于跟蹤用戶點(diǎn)擊頁(yè)面或動(dòng)態(tài)廣告曝光次數(shù),如:
<input type="button" id="btn" value="圖像Ping請(qǐng)求" />
<div id="result"></div>
<script>
var increment = (function(){
var counter = 0;
return function(){
return ++counter;
};
})();
var btn = document.getElementById("btn");
btn.addEventListener("click", function(event){
var sum = increment();
var result = document.getElementById("result");
var img = result.getElementsByTagName("img")[0];
if(!img)
img = new Image();
img.onload = img.onerror = function(){
result.appendChild(img);
var oSpan = document.getElementById("sum");
if(!oSpan){
oSpan = document.createElement("span");
oSpan.id = "sum";
}
oSpan.innerHTML = "發(fā)送請(qǐng)求的次數(shù):" + sum;
result.appendChild(oSpan);
};
if(sum % 2)
img.src = "https://www.zeronetwork.cn/study/images/ad1.jpg?sum=" + sum;
else
img.src = "https://www.zeronetwork.cn/study/images/ad2.jpg?sum="+sum;
</script>
基于<script>標(biāo)簽實(shí)現(xiàn)跨域:
在某些HTML元素中,可以通過它的src屬性跨域請(qǐng)求內(nèi)容,例如img、iframe等,也就是沒有跨域的限制;同樣,script也可以,也就是利用script來執(zhí)行跨域的javascript代碼,從而實(shí)現(xiàn)前端跨域請(qǐng)求數(shù)據(jù)的目的;例如:
<script>
var script = document.createElement('script');
script.src = "http://www.b.com/scripts/demo.js";
document.body.appendChild(script);
script.onload = function(){
show("從a.com傳過去的數(shù)據(jù)");
}
</script>
b.com/scripts/demo.js:
function show(msg){
alert("收到的數(shù)據(jù):" + msg);
}
alert("www.b.com/script/demo.js");
JSONP:
JSONP是JSON with padding(填充式JSON或參數(shù)式JSON)的簡(jiǎn)寫,是應(yīng)用JSON的新方法,其利用<script>標(biāo)簽沒有跨域限制的特點(diǎn),可以得到從其他源動(dòng)態(tài)產(chǎn)生的JSON數(shù)據(jù),但JSONP請(qǐng)求一定需要對(duì)方服務(wù)器的支持才可以;
JSONP看起來與JSON差不多,是被包含在函數(shù)調(diào)用中的JSON,形如:callback({“name”: “wangwei”});
JSONP由兩部分組成:回調(diào)函數(shù)callback和json數(shù)據(jù);回調(diào)函數(shù)是當(dāng)響應(yīng)到來時(shí)應(yīng)該在頁(yè)面中調(diào)用的函數(shù),其名字一般是在請(qǐng)求中指定的,需要在本地實(shí)現(xiàn);而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù);整個(gè)JSONP就是一個(gè)標(biāo)準(zhǔn)的JavaScript語句;
JSONP后端服務(wù):被請(qǐng)求服務(wù)端程序必須提供JSONP的服務(wù),一般情況下,其會(huì)返回標(biāo)準(zhǔn)的JSONP;
例如,被請(qǐng)求服務(wù)端b.com/jsonptest.php返回JSONP的簡(jiǎn)單形式:
<?php
echo 'alert({"name":"王唯","age":18})';
在請(qǐng)求端中使用<script>引入該文件,如:
<script src="http://www.b.com/jsonptest.php"></script>
請(qǐng)求端和服務(wù)端共同約定使用自定義函數(shù),而不是內(nèi)置函數(shù);例如b.com/jsonptest.php:
echo 'handlerJSONP({"name":"王唯","age":18})';
請(qǐng)求端實(shí)現(xiàn)handlerJSONP()函數(shù),并使用<script>引入b.com/jsonptest.php文件,如:
<script>
function handlerJSONP(response){
alert("姓名:" + response.name + "\n" + "年齡:" + response.age);
}
</script>
<script src="http://www.b.com/jsonptest.php"></script>
一般來說,后端程序通過查詢字符串允許客戶端指定一個(gè)函數(shù)名,然后用這個(gè)函數(shù)名去填充響應(yīng),例如:
<script>
function handlerJSONP(response){
alert(response);
}
</script>
<script src="http://www.b.com/jsonptest.php?callback=handlerJSONP"></script>
b.com/jsonptest.php:
header('Content-type: application/json');
//獲取回調(diào)函數(shù)名
$callback = htmlspecialchars($_REQUEST['callback']);
//json數(shù)據(jù)
$json_data = '["王唯","靜靜","娟子","大國(guó)"]';
//輸出jsonp格式的數(shù)據(jù)
echo $callback . "(" . $json_data . ")";
JSONP是通過動(dòng)態(tài)<script>元素來使用的,例如:
// ...
var script = document.createElement("script");
script.src = "http://www.b.com/jsonptest.php?callback=handlerJSONP";
document.body.insertBefore(script, document.body.firstChild);
請(qǐng)求端與后端就該函數(shù)名有個(gè)約定,使用隨機(jī)名,如:hander1234();而查詢字符串的名字一般約定使用”json”或”callback”,當(dāng)然也可以是其他任意的名稱;
JSONP之所以在開發(fā)人員中極為流行,主要原因是它非常簡(jiǎn)單易用;與圖像Ping相比,它的優(yōu)點(diǎn)在于能夠直接獲取響應(yīng)文本,支持在瀏覽器與服務(wù)器之間雙向通信;
在某些時(shí)候,處理完JSONP數(shù)據(jù)后,動(dòng)態(tài)創(chuàng)建的<script>就可以刪除了;
function clickHandler(e){
var script = document.createElement("script");
script.id = "jsonp_script";
script.src = "http://www.a.com/jsonp.php?callback=handlerResponse";
document.body.insertBefore(script, document.body.firstChild);
}
function handlerResponse(response){
console.log(response);
var script = document.getElementById("jsonp_script");
script.parentNode.removeChild(script);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", clickHandler);
定義將被腳本執(zhí)行的回調(diào)函數(shù)
getJSONP[cbnum] = function(response){
try{
callback(response);
}finally{
delete getJSONP[cbnum];
script.parentNode.removeChild(script);
}
};
script.src = url;
document.body.appendChild(script);
}
getJSONP.counter = 0; // 用于創(chuàng)建唯一回調(diào)函數(shù)名稱的計(jì)數(shù)器
function handlerResponse(response){
console.log(response);
}
getJSONP("http://www.a.com/jsonp.php", handlerResponse);
示例:某接口的應(yīng)用:
<input type="button" id="btn" value="jsonp請(qǐng)求">
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
var script = document.createElement("script");
script.id = "jsonscript";
script.src = "https://suggest.taobao.com/sug?code=utf-8&q="+ encodeURIComponent("衣服") +"&callback=jsonpCallback";
document.body.appendChild(script);
});
function jsonpCallback(response){
console.log(response);
var script = document.getElementById("jsonscript");
script.parentNode.removeChild(script);
}
</script>
JSONP的不足:
JSONP和AJAX對(duì)比:
JSONP和AJAX相同,都是客戶端向服務(wù)器端發(fā)送請(qǐng)求,從服務(wù)器端獲取數(shù)據(jù)的方式;但AJAX屬于同源策略,采用CORS方案跨域,而JSONP屬于非同源策略進(jìn)行跨域請(qǐng)求;
window.postMessage()方法:
window.postMessage()方法可以安全地實(shí)現(xiàn)跨域通信;其是HTML5規(guī)范提供的一種受控機(jī)制來規(guī)避跨域安全限制的方法,采用異步的方式進(jìn)行有限的通信,既可以用于同域傳遞消息,也可以用于跨域傳遞消息;
其應(yīng)用的場(chǎng)景是:
一個(gè)窗口可以獲得對(duì)另一個(gè)窗口的引用,比如iframe的contentWindow屬性、執(zhí)行window.open返回的窗口對(duì)象、或者是命名過或數(shù)值索引的window.frames,然后在窗口上調(diào)用targetWindow.postMessage()方法分發(fā)一個(gè)MessageEvent消息;接收消息的窗口觸發(fā)onmessage事件,并接收分發(fā)過來的消息;
例如a.com/post.html,獲取iframe:
<h1>a.com/post.html</h1>
<iframe id="iframe" src="http://www.b.com/message.html"></iframe>
<script>
var iframe = document.getElementById("iframe");
var win = iframe.contentWindow;
console.log(win);
</script>
b.com/ message.html:
<h1>b.com/message.html</h1>
語法:otherWindow.postMessage(message, targetOrigin, [transfer]);
例如:a.com/post.html:
// ...
win.postMessage("來自a.com/post.html的消息","*");
b.com/message.html:
window.addEventListener("message", function(event){
console.log(event); // MessageEvent
});
需要延遲執(zhí)行postMessage()方法,延遲的方式有多種,使用setTimeout()、iframe的onload事件、發(fā)送者的onload事件或者使用按鈕的click事件處理程序,如a.com/post.html:
setTimeout(function(){
win.postMessage("來自a.com/post.html的消息","*");
},500);
// 或:
var iframe = document.getElementsByTagName("iframe")[0];
iframe.onload = function() {
var iframe = document.getElementById("iframe");
var win = iframe.contentWindow;
win.postMessage("來自a.com/post.html的消息","*");
}
// 或:
var btnSend = document.getElementById("btnSend");
btnSend.addEventListener("click", function(){
var iframe = document.getElementsByTagName("iframe")[0];
var win = iframe.contentWindow;
win.postMessage("來自a.com/post.html的消息","*");
});
使用postMessage()將數(shù)據(jù)發(fā)送到其他窗口時(shí),最好指定明確的targetOrigin,而不是*,原因是惡意網(wǎng)站可以在用戶不知情的情況下更改窗口的位置,甚至可以攔截所發(fā)送的數(shù)據(jù);
win.postMessage("來自a.com/post.html的消息","http://www.b.com"); // 或
win.postMessage("來自a.com/post.html的消息","http://www.b.com/"); // 或
win.postMessage("來自a.com/post.html的消息","http://www.b.com/error.html");
在發(fā)送消息的時(shí)候,如果目標(biāo)窗口的協(xié)議、主機(jī)地址或端口這三者的任意一項(xiàng)不匹配targetOrigin的值,那么消息就不會(huì)被發(fā)送;只有三者完全匹配,消息才會(huì)被發(fā)送;這個(gè)機(jī)制用來控制消息可以發(fā)送到哪些窗口。
MessageEvent接口:
代表一段被目標(biāo)對(duì)象接收的消息;
屬性:
window.addEventListener("message", function(event){
console.log(event);
console.log(event.data); // 來自a.com/post.html的消息
console.log(event.lastEventId); // 空
console.log(event.origin); // http://www.a.com
console.log(event.ports); // []
console.log(event.source); // window http://www.a.com/post.html
});
如果不希望接收message,就不要實(shí)現(xiàn)message事件;如果希望從其他網(wǎng)站接收message,最好使用origin或source屬性驗(yàn)證消息發(fā)送者的身份;如:
window.addEventListener("message", function(event){
if(event.origin != "http://www.a.com")
return;
console.log(event.data);
});
雖然postMessage()是單向的通信,但可以使用source屬性在具有不同origin的兩個(gè)窗口之間建立雙向通信;
例如a.com/message.html:
<iframe id="iframe" src="http://www.b.com/message.html"></iframe>
<input type="button" id="btn" value="send" />
<script>
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
var iframe = document.getElementById("iframe");
var win = iframe.contentWindow;
win.postMessage("來自a.com/post.html的消息","http://www.b.com/");
});
window.addEventListener("message", function(event){
console.log("a.com收到:" + event.data);
});
</script>
b.com/message.html:
window.addEventListener("message", function(event){
if(event.origin != "http://www.a.com")
return;
console.log("b.com收到:" + event.data);
event.source.postMessage("b.com/message回發(fā)的消息", event.origin);
});
與使用open()方法打開的窗口通信:
在向使用open()方法打開的窗口發(fā)送消息時(shí),需要延遲執(zhí)行,如:
btnOpen.addEventListener("click", function(){
var win = window.open("http://www.b.com/message.html","_blank","width:600px,height:400px");
setTimeout(function(){
win.postMessage("從a.com中打開","http://www.b.com");
},1000);
});
window.addEventListener("message", function(event){
console.log("a.com收到:" + event.data);
});
或者反向發(fā)送消息,例如a.com/post.html:
var btnOpen = document.getElementById("btnOpen");
btnOpen.addEventListener("click", function(){
var win = window.open("http://www.b.com/message.html","_blank","width:600px,height:400px");
});
window.addEventListener("message", function(event){
console.log("a.com收到:" + event.data);
});
b.com/message.html:
<script>
window.onload = function(){
var targetWindow = window.opener;
console.log(targetWindow);
targetWindow.postMessage("message.html is ready","http://www.a.com");
}
window.addEventListener("message", function(event){
console.log("b.com收到:");
console.log(event.data);
event.source.postMessage("b.com/message.html回發(fā)的消息", event.origin);
});
</script>
postMessage()還可以發(fā)送結(jié)構(gòu)化數(shù)據(jù),該數(shù)據(jù)將會(huì)自動(dòng)被(結(jié)構(gòu)化克隆算法)序列化,如:
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
var iframe = document.getElementById("iframe");
var win = iframe.contentWindow;
var person = {
name:"wanwei",
sex: true,
age: 18,
friends: ["jingjing","daguo"],
// smoking: function(){console.log(this.name)}, // 異常 could not be cloned.
other1: undefined,
other2: null
}
win.postMessage(person,"http://www.b.com/");
b.com/message.html:
window.addEventListener("message", function(event){
console.log("b.com收到:");
console.log(event.data);
});
因?yàn)槭强缬颍约词谷〉猛庠创翱诘膚indow對(duì)象,也無法操作對(duì)方的DOM,但是通過接收到的消息,自行構(gòu)建DOM;
例如a.com/post.html:
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
var iframe = document.getElementById("iframe");
var win = iframe.contentWindow;
var person = {
name:"wanwei",
sex: true,
age: 18,
friends: ["jingjing","daguo"],
}
win.postMessage(person,"http://www.b.com/");
});
window.addEventListener("message", function(event){
if(event.origin == "http://www.b.com"){
if(event.data.state){
document.getElementById("btn").setAttribute("disabled",true);
// ...
}
}
});
b.com/message.html:
window.addEventListener("message", function(event){
if(event.origin == "http://www.a.com"){
var person = event.data;
var h1 = document.createElement("h1");
h1.innerText = person.name + "信息";
document.body.appendChild(h1);
var p = document.createElement("p");
p.innerHTML = "性別:" + (person.sex ? "男" : "女");
p.innerHTML += "<br/>年齡:" + person.age;
p.innerHTML += "<br/>朋友:" + person.friends.join(",");
document.body.appendChild(p);
event.source.postMessage({state:1}, event.origin);
}
});
示例,后臺(tái)管理的應(yīng)用,main.html:
<style>
*{margin:0; padding:0;}
ul,li{list-style: none;}
.top{width:100%; height:100px; background-color:yellowgreen;}
.left{width:20%; height: 100%; float: left; background-color:yellow;}
.left ul li{padding:10px;}
.left ul li a{color:#000; text-decoration: none;}
iframe{width:80%; float: right; border:none;}
.bg{
position: fixed; left:0; top: 0; display: none;
width:100%; height:100%; background-color: rgba(0, 0, 0, .5);
}
.showBg{display: block !important}
.confirm{
position:fixed; width:400px; height:200px; z-index: 2;
left: 50%; top: 50%; transform: translate(-50%, -50%);
padding: 20px; text-align: center; background-color: #FFF;
}
</style>
<div class="top"></div>
<div class="left">
<ul>
<li><a href="console.html" target="iframe">控制臺(tái)</a></li>
<li><a href="content.html" onclick="sendMessage()" target="iframe">系統(tǒng)設(shè)置</a></li>
</ul>
</div>
<iframe name="iframe" src="console.html"></iframe>
<div class="bg">
<div class="confirm">
<p>是否確認(rèn)保存?</p>
<p><input type="button" id="btnCancel" value="取消" />
<input type="button" id="btnSave" value="保存" /></p>
</div>
</div>
<script>
var iframe = null;
window.onload = function(){
var leftDiv = document.getElementsByClassName("left")[0];
iframe = document.getElementsByTagName("iframe")[0];
iframe.style.height = leftDiv.style.height = (document.documentElement.scrollHeight - 100) + "px";
}
function sendMessage(){
iframe.onload = function(){
iframe.contentWindow.postMessage({
method: 'dataId',
data: {dataId: 1}
}, "*");
}
}
window.addEventListener("message", function(event){
if(event.data.method == "showBg"){
document.getElementsByClassName("bg")[0].classList.add("showBg");
}
});
var btnCancel = document.getElementById("btnCancel");
btnCancel.addEventListener("click", function(){
if(iframe){
iframe.contentWindow.postMessage({
method: "cancel"
}, "*");
document.getElementsByClassName("bg")[0].classList.remove("showBg");
}
});
var btnSave = document.getElementById("btnSave");
btnSave.addEventListener("click", function(){
if(iframe){
iframe.contentWindow.postMessage({
method: "save"
}, "*");
document.getElementsByClassName("bg")[0].classList.remove("showBg");
}
});
</script>
console.html:
<h1>控制臺(tái)</h1>
content.html:
<style>
.container{width:60%; margin: 0 auto;}
</style>
<div class="container">
<p>設(shè)置1:<input type="text" /></p>
<p>設(shè)置2:<input type="text" /></p>
<p>設(shè)置3:<input type="text" /></p>
<p>設(shè)置4:<input type="text" /></p>
<p><input type="button" id="btnConfirm" value="保存" /></p>
</div>
<script>
window.addEventListener("message", function(event){
if(event.data.method == "dataId"){
console.log(event.data.data.dataId);
}else if(event.data.method == "cancel"){
console.log("取消操作");
}else if(event.data.method == "save"){
console.log("保存成功");
}
});
var btnConfirm = document.getElementById("btnConfirm");
btnConfirm.addEventListener("click", function(){
window.parent.postMessage({
method: "showBg"
}, "*");
});
</script>
示例,修改信息:
content.html:
<div class="container">
<h1>用戶信息</h1>
<p>ID:001</p>
<p>姓名:<span id="usernameSpan">王唯</span>
<input type="button" id="editInfo" value="修改個(gè)人信息" /> </p>
<p>單位:<span id="jobSpan">零點(diǎn)網(wǎng)絡(luò)</span>
<input type="button" id="editJob" value="修改工作信息" /></p>
<p>地址:<input type="text" id="address" value="北京市東城區(qū)" /></p>
<p>電話:<input type="text" id="tel" value="13888888888" /></p>
<p><input type="button" id="btnConfirm" value="保存" /></p>
</div>
<script>
window.addEventListener("message", function(event){
if(event.data.method == "dataId"){
console.log(event.data.data.dataId);
}else if(event.data.method == "cancel"){
console.log("取消操作");
}else if(event.data.method == "save"){
document.getElementById("usernameSpan").innerText = event.data.data.username;
console.log("保存成功");
}
});
var btnConfirm = document.getElementById("btnConfirm");
btnConfirm.addEventListener("click", function(){
window.parent.postMessage({
method: "showBg"
}, "*");
});
var editInfo = document.getElementById("editInfo");
editInfo.addEventListener("click", function(){
var win = window.open("editInfo.html", "_blank","width:200px,height:500px");
setTimeout(function(){
win.postMessage({
method: "info",
dataId: 2
});
},500);
});
</script>
editInfo.html:
<form>
<input type="hidden" id="ID" name="ID" />
<p>姓名:<input type="text" id="username" name="username" /></p>
<p>性別:<input type="radio" id="male" name="sex" value="1" />男
<input type="radio" id="female" name="sex" value="0" />女</p>
<p>年齡:<input type="text" id="age" name="age" /></p>
<p><input type="button" id="btnCancel" value="取消" />
<input type="button" id="btnSave" value="保存" /></p>
</form>
<script>
window.addEventListener("message", function(event){
if(event.data.method == "info"){
// Ajax請(qǐng)求,從數(shù)據(jù)庫(kù)中取出這條記錄
var id = event.data.dataId;
var xhr = new XMLHttpRequest();
xhr.open("GET", "getInfo.php?action=showInfo&ID=" + id);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
// console.log(xhr.response);
var person = xhr.response;
document.forms[0].elements['ID'].value = person.ID;
document.forms[0].elements['username'].value = person.username;
document.forms[0].elements['sex'].value = person.sex;
document.forms[0].elements['age'].value = person.age;
xhr = null;
}
};
xhr.responseType = "json";
xhr.send(null);
}
});
var btnCancel = document.getElementById("btnCancel");
btnCancel.addEventListener("click", function(){
window.opener.postMessage({method: "cancel"}, "*");
window.close();
});
var btnSave = document.getElementById("btnSave");
btnSave.addEventListener("click", function(){
// 保存到數(shù)據(jù)庫(kù)
var data = new FormData(document.forms[0]);
data.append("action", "update");
var xhr = new XMLHttpRequest();
xhr.open("POST", "getInfo.php");
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var data = JSON.parse(xhr.responseText);
if(data.status){
var person = {
ID: document.forms[0].elements['ID'].value,
username: document.forms[0].elements['username'].value,
sex: document.forms[0].elements['sex'].value,
age: document.forms[0].elements['age'].value
};
window.opener.postMessage({
method: "save",
data: person
});
}
xhr = null;
}
};
xhr.send(data);
window.close();
})
</script>
editInfo.php:
<?php
require_once "conn.php";
if(isset($_REQUEST['action'])){
if($_REQUEST['action'] == 'showInfo'){
$ID = intval($_GET['ID']);
$sql = "select ID,username, sex, age from users where ID=$ID";
$result = $conn->query($sql);
$row = mysqli_fetch_array($result);
echo json_encode($row);
}elseif($_REQUEST['action'] == 'update'){
$ID = intval($_POST['ID']);
$username = $_POST['username'];
$sex = $_POST['sex'];
$age = $_POST['age'];
$sql = "update users set username='$username', sex='$sex', age='$age' where ID=$ID";
$result = $conn->query($sql);
if($result){
echo '{"status": 1}';
}else{
echo '{"status": 0}';
}
}
超鏈接打開的窗口也可使用postMessage()方法進(jìn)行通信,但需要設(shè)置a標(biāo)簽的target屬性為自定義值,如:
<p><a href="http://www.b.com/content.html" target="mywin">零點(diǎn)程序員</a></p>
b.com/content.html:
console.log(window.opener); // Window or global
console.log(window.name); // "mywin"
發(fā)送消息,b.com/content.html:
if(window.opener){
console.log(window.opener);
window.opener.postMessage("我已經(jīng)打開了","*");
}
主頁(yè)面:
/一、html
//a、HTML語法規(guī)范
//a.1基本語法概述
1、HTML標(biāo)簽是由尖括號(hào)包圍的關(guān)鍵字,例如,
2、HTML標(biāo)簽通常是成對(duì)出現(xiàn)的,例如和,我們成為雙標(biāo)簽,標(biāo)簽對(duì)中的第一個(gè)標(biāo)簽是開始標(biāo)簽,第二個(gè)標(biāo)簽是結(jié)束標(biāo)簽。
3、有些特殊的標(biāo)簽是單個(gè)標(biāo)簽(極少情況),例如
,我們稱為單標(biāo)簽
//a.2標(biāo)簽關(guān)系
雙標(biāo)簽關(guān)系可以分為兩類:包含關(guān)系和并列關(guān)系。
//b、HTML基本結(jié)構(gòu)標(biāo)簽
//b.1第一個(gè)HTML網(wǎng)頁(yè)
每個(gè)網(wǎng)頁(yè)都會(huì)有一個(gè)基本的結(jié)構(gòu)標(biāo)簽(也稱為骨架標(biāo)簽),頁(yè)面內(nèi)容也是在這些基本標(biāo)簽上寫的。
HTML頁(yè)面也稱為HTML文檔
標(biāo)簽名 | 定義 | 說明 |
<html></html> | HTML標(biāo)簽 | 頁(yè)面中最大的標(biāo)簽,我們稱為根標(biāo)簽 |
<head></head> | 文檔的頭部 | 注意在head標(biāo)簽中我們必須要設(shè)置的標(biāo)簽是title |
<title></title> | 文檔的標(biāo)題 | 讓頁(yè)面擁有一個(gè)屬于自己的網(wǎng)頁(yè)標(biāo)題 |
<body></body> | 文檔的主體 | 元素包含文檔的所有內(nèi)容,頁(yè)面內(nèi)容,基本都是放到body里面的 |
必須是.html或.htm,瀏覽器的作用是讀取HTML文檔,并以網(wǎng)頁(yè)的形式顯示出它們。
此時(shí),用瀏覽器打開這個(gè)網(wǎng)頁(yè),我們就可以預(yù)覽我們寫的第一個(gè)HTML文件了。
//c、開發(fā)工具vscode
1、<!DOCTYPE>標(biāo)簽
文檔類型聲明,作用就是告訴瀏覽器使用哪種HTML版本來顯示網(wǎng)頁(yè)
<!DOCTYPE html>這句代碼的意思是:當(dāng)前頁(yè)面采用的是HTML5來顯示頁(yè)面。
2、lang語言
用來定義當(dāng)前文檔顯示的語言:
a、en定義語言為英語
b、zh-CN定義語言為中文
簡(jiǎn)單來說定義為en就是英文網(wǎng)頁(yè),定義為zh-CN就是中文網(wǎng)頁(yè)
其實(shí)對(duì)于文檔顯示來說,定義成en的文檔也可以顯示中文,定義zh-CN的文檔也可以顯示英文
這個(gè)屬性對(duì)于瀏覽器和搜索引擎(百度、谷歌等)還是有作用的
3、charset字符集
字符集是多個(gè)字符的集合,以便計(jì)算機(jī)能夠識(shí)別和存儲(chǔ)各種文字
在標(biāo)簽內(nèi),通過標(biāo)簽的charset屬性來規(guī)定HTML文檔應(yīng)該使用哪種字符編碼。
charset常用的值:GB2312、BIG5、GBK和UTF-8,其中UTF-8也稱為萬國(guó)碼,基本包含了全世界所有國(guó)家需要用到的字符。
注意:上面語法是必須寫的代碼,否則可能引起亂碼的情況,一般情況下,統(tǒng)一使用"UTF-8"編碼,盡量統(tǒng)一寫成標(biāo)準(zhǔn)的"UTF-8",不要寫成"utf-8"或"UTF8"。
//d、HTML常用標(biāo)簽
//d.1標(biāo)簽語義
學(xué)習(xí)標(biāo)簽是有技巧的,重點(diǎn)是記住每個(gè)標(biāo)簽的語義,簡(jiǎn)單理解就是指標(biāo)簽的含義,即這個(gè)標(biāo)簽是用來干嘛的
根據(jù)標(biāo)簽的語義,在合適的地方給一個(gè)最為合理的標(biāo)簽,可以讓頁(yè)面結(jié)構(gòu)更清晰。
//d.2標(biāo)題標(biāo)簽
-
(重要)
為了使網(wǎng)頁(yè)更具有語義,我們經(jīng)常會(huì)在頁(yè)面中用到標(biāo)題標(biāo)簽,HTML提供了6個(gè)等級(jí)的網(wǎng)頁(yè)標(biāo)題集
-
特點(diǎn):
1、加了標(biāo)題的文字會(huì)變得更加粗,字號(hào)也會(huì)依次變大。
2、一個(gè)標(biāo)題獨(dú)占一行。
//d.3段落和換行標(biāo)簽(重要)
在網(wǎng)頁(yè)中,要把文字有條理地顯示出來,就需要將這些文字分段顯示,在HTML標(biāo)簽中,
標(biāo)簽用于定義段落,它可以將整個(gè)網(wǎng)頁(yè)分為若干段落。
<p>我是一個(gè)段落標(biāo)簽</p>標(biāo)簽語義:可以把HTML文檔分割為若干段落。
特點(diǎn):
1、文本在一個(gè)段落中會(huì)根據(jù)瀏覽器窗口的大小自動(dòng)換行。
2、段落和段落之間保有一個(gè)較大的空隙。
在HTML中,一個(gè)段落中的文字從左到右依次排列,直到瀏覽器的右端,然后自動(dòng)換行,如果希望某段文本強(qiáng)制換行顯示,就需要使用換行標(biāo)簽
<br />
單詞break的縮寫,意為打斷,換行。
特點(diǎn):
1、單標(biāo)簽
2、
標(biāo)簽只是簡(jiǎn)單地開始新的一行,跟段落不一樣,段落之間會(huì)插入一些垂直的間距。
//d.4文本格式標(biāo)簽
在網(wǎng)頁(yè)中,有時(shí)需要為文字設(shè)置粗體,斜體或下劃線等效果,這時(shí)就需要用到HTML中的文本格式標(biāo)簽,使文字以特殊的方式顯示
標(biāo)簽語義:突出重要性,比普通文字更重要。
語義 | 標(biāo)簽 | 說明 |
加粗 | <strong></strong>或者<b></b> | 更推薦使用<strong></strong>標(biāo)簽加粗,語義更強(qiáng)烈 |
傾斜 | <em><em> 或者<i><i> | 更加推薦使用<em><em>標(biāo)簽,語義更加強(qiáng)烈 |
刪除線 | <del><del>或者<s><s> | 更加推薦使用<del><del>標(biāo)簽,語義更加強(qiáng)烈 |
下劃線 | <ins><ins>或者<u><u> | 更加推薦<ins><ins>標(biāo)簽,語義更加強(qiáng)烈 |
//d.5<div>和<span>標(biāo)簽
<div>和<span>是沒有語義的,它們就是一個(gè)盒子,用來裝內(nèi)容。
<div>這是頭部</div>
<span>今日價(jià)格</span>
div是division的縮寫,表示分割,分區(qū),span意為跨度,跨距。
特點(diǎn):
1、<div>標(biāo)簽用來布局,但是現(xiàn)在一行只能放一個(gè)<div>,大盒子。
2、<span>標(biāo)簽用來布局,一行上可以有多個(gè)<span>,小盒子
//d.6圖像標(biāo)簽和路徑(重點(diǎn))
1、圖像標(biāo)簽
在HTML標(biāo)簽中,<img>標(biāo)簽用于定義HTML頁(yè)面中的圖像。
<img src="圖像url"/>
單詞image的縮寫,意為圖像
src是<img>標(biāo)簽的必須屬性,它用于指定圖像文件的路徑和文件名。
所謂屬性:簡(jiǎn)單理解就是屬于這個(gè)圖像標(biāo)簽的特性。
圖像標(biāo)簽的其他屬性:
屬性 | 屬性值 | 說明 |
src | 圖片路徑 | 必須屬性 |
alt | 文本 | 替換文本,圖像不能顯示的文字 |
title | 文本 | 提示文本,鼠標(biāo)放到圖像上,顯示文字 |
width | 像素 | 設(shè)置圖像的寬度 |
height | 像素 | 設(shè)置圖像的高度 |
border | 像素 | 設(shè)置圖像的邊框粗細(xì) |
HTML:htper text markup language超文本標(biāo)記(標(biāo)簽)語言
由各種標(biāo)簽組成,用來制作網(wǎng)頁(yè),告訴瀏覽器如何顯示頁(yè)面
w3c:world wide web consortium萬維網(wǎng)聯(lián)盟,制定web技術(shù)相關(guān)標(biāo)準(zhǔn)和規(guī)范的組織,HTML技術(shù)hi由w3c制定的標(biāo)準(zhǔn)
兩個(gè)版本:HTML4.0.1、HTML5.0-----通常H5
官網(wǎng):http://www.W3shcool.com.cn
HTML文檔是以.html或.htm結(jié)尾
記事本notepad、sublime、Notepad++、Dreamweaver、VScode、Webstorm等
使用步驟:
使用技巧:
常見的瀏覽器:IE瀏覽器微軟、chrome谷歌瀏覽器、fifirefox火狐、safari蘋果
瀏覽器的作用是讀取html文件,并以網(wǎng)頁(yè)的形式來顯示
瀏覽器不會(huì)直接顯示html標(biāo)簽,而是使用標(biāo)簽來解釋網(wǎng)頁(yè)的內(nèi)容
一個(gè)完整的html標(biāo)簽的組成:
<標(biāo)簽名 屬性名="屬性值">內(nèi)容</標(biāo)簽名>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>標(biāo)簽</title>
</head>
<body bgcolor="red" text="blue">
html從入門到精通!
</body>
</html>
12345678910
屬性值要用雙撇號(hào)括起來,一般用雙引號(hào)
根據(jù)標(biāo)簽是否關(guān)閉,分為,關(guān)閉型和非關(guān)閉型
<html></html>
<head></head>
<title></title>
非關(guān)閉型:沒有結(jié)束標(biāo)簽
<meta>
<br>
<h1>....<h6>
根據(jù)標(biāo)簽是否獨(dú)占一行,分為塊級(jí)標(biāo)簽和行級(jí)標(biāo)簽
塊級(jí)標(biāo)簽:顯示為塊狀,獨(dú)占一行
<h1>大家好</h1>
<hr>
行級(jí)標(biāo)簽:在行內(nèi)顯示,可與其他內(nèi)容在同一行顯示
<span></span>
注釋在瀏覽器中不會(huì)顯示,是用來標(biāo)注解釋html語句,但通過查看源代碼的方式可以看到
語法:
<--注釋內(nèi)容-->
也稱為特殊字符,用于顯示一些特殊符號(hào),如<>&空格等
語法:
<&實(shí)體字符的名稱>
在html文檔的第一行,使用<!DOCTYPE html>
聲明HTML文檔的類型用來告訴瀏覽器頁(yè)面的文檔嘞型,用來制定html版本的規(guī)范
目前基本上最常用的html5
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
</html>
12345678910
1.基本標(biāo)簽
1.1 有序列表
ol:ordered listli:list item默認(rèn)使用阿拉伯?dāng)?shù)字、從1開始標(biāo)記,可以通過屬性進(jìn)行修改
· type屬性:設(shè)置列表的符號(hào)標(biāo)記、取值;數(shù)字1(默認(rèn))、字母(a或A)、羅馬數(shù)字(i或I) · start屬性:設(shè)置起始值,值必須是數(shù)字
1.2 無序列表
ul:unodered list
li:list item
默認(rèn)情況下使用實(shí)心圓表作為符號(hào)標(biāo)記,可以通過屬性進(jìn)行修改
· type屬性:設(shè)置列表的符號(hào)標(biāo)記、取值:disc實(shí)心圓(默認(rèn))、circle空心圓、square正方形、none不 顯示項(xiàng)目符號(hào)
1.3 定義列表
dl:definition list
dt:definition title
dd:definition description
1.4 水平線標(biāo)簽
hr:horizontal
常用屬性:
· color:顏色
兩種方式:
顏色名稱:如red、green、blue、white、black、pink、orange等
16進(jìn)制的RGB表示法:Red、Green、Blue用法:#RRGGBB 每種顏色的取值范值0-255,轉(zhuǎn)換為16 進(jìn)制00-FF
如: #FF0000 紅色 #00FF00綠色 #0000FF藍(lán)色 #FFFFFF白色、#CCCCCC #FF7300桔色
· size:粗細(xì),數(shù)值
· width寬度
兩種寫法:
? 像素:絕對(duì)值(固定值)
? 百分比:相對(duì)值,相對(duì)于水平線標(biāo)簽所在父容器寬度的百分比
· align對(duì)齊
? 取值:center居中 left right
1.5圖像標(biāo)簽
img:image
常見的圖片格式:.jpg .png .gif .bmp
常見的屬性:
· src:source指定圖片的路徑(來源),必選叁數(shù)
如果圖片與html源代碼在同一個(gè)文件夾中,可以直接在src中寫圖片名稱即可
習(xí)慣上,我們會(huì)將多個(gè)圖片與html代碼文檔分別放在同一個(gè)文件夾project中的不同目錄下,此時(shí)需要 在src中指定圖片的路徑為相對(duì)路徑
路徑的分類:
? · 相對(duì)路徑
? 表示: ./當(dāng)前路徑
…/當(dāng)前位置的上一級(jí)文件夾
? 提示:…/image
? · alt:當(dāng)圖片無法顯示時(shí)顯示的提示信息
? · title:當(dāng)鼠標(biāo)放到圖片上時(shí)顯示的提示信息
? · width和 height:設(shè)置圖片的寬度和高度
默認(rèn)圖片以原始尺寸顯示
? 如果只設(shè)置其中一個(gè),則另一個(gè)會(huì)按比例縮放
? 如果同時(shí)設(shè)置寬和高,可能導(dǎo)致圖片變形
? 兩種寫法:
? 像素:絕對(duì)值(固定值)
? 百分比:相對(duì)值,相對(duì)于父容器的尺寸的百分比
2.其他標(biāo)簽
為了更好語義化
3.頭部標(biāo)簽
· meta定義網(wǎng)頁(yè)的摘要信息,如字符編碼,關(guān)鍵詞,描述,作者等
· title定義網(wǎng)頁(yè)的標(biāo)題
· style定義內(nèi)容css樣式
· link引用外部css樣式
· script定義或引用腳本
· base定義基礎(chǔ)路徑
默認(rèn)以當(dāng)前頁(yè)面文件所在的位置為相對(duì)路徑參照
4.標(biāo)簽嵌套
一個(gè)標(biāo)簽中嵌套另外一個(gè)標(biāo)簽
標(biāo)簽不能亂嵌套
瀏覽器渲染后顯示的頁(yè)面代碼與編碼時(shí)有所不同
chrome瀏覽器提供的開發(fā)工具:幫助開發(fā)人員查看和調(diào)試頁(yè)面的
如何打開:
· Elements:從瀏覽器的角度來看頁(yè)面,瀏覽器渲染頁(yè)面時(shí)內(nèi)部的結(jié)構(gòu)
· console:控制臺(tái),顯示各種警告和錯(cuò)誤信息
· network:查看網(wǎng)絡(luò)請(qǐng)求信息,瀏覽器向服務(wù)器請(qǐng)求了哪些資源,資源大小,
加載資源所消耗的時(shí)間
四、超鏈接
1.簡(jiǎn)介
使用超鏈接可以從一個(gè)頁(yè)面跳轉(zhuǎn)到另外一個(gè)頁(yè)面,實(shí)現(xiàn)頁(yè)面之間導(dǎo)航
當(dāng)鼠標(biāo)移動(dòng)到超鏈接文本或圖片時(shí),鼠標(biāo)箭頭會(huì)變成一只小手
超鏈接有三種類型:
普通鏈接/頁(yè)面間的鏈接,跳轉(zhuǎn)到另一個(gè)頁(yè)面 錨鏈接:鏈接到錨點(diǎn)(鏈接到同一個(gè)頁(yè)面的指定位置) 功能鏈接:實(shí)現(xiàn)特殊功能(發(fā)郵件,下載)
2.基本用法
使用 標(biāo)簽來創(chuàng)建超鏈接
語法格式:
常用屬性:
href:鏈接地址或路徑,鏈接地址
world
鏈接文本或圖片
1 2 3 4 5 1 target:鏈接打開的位置,取值
路徑分類:
絕對(duì)路徑 以根開始的路徑
file:///D:/software/b.html https://www.baidu.com/img/bd_logo1.png
相對(duì)路徑 相對(duì)于當(dāng)前頁(yè)面文件所在的路徑,不是以根開始的路徑 ./ 當(dāng)前路徑 …/ 當(dāng)前位置上一級(jí)目錄
3.錨鏈接
3.1簡(jiǎn)介
點(diǎn)擊鏈接后跳轉(zhuǎn)到某一個(gè)頁(yè)面的指定位置(錨點(diǎn)anchor)
錨鏈接的分類:
頁(yè)面內(nèi)的錨鏈接 頁(yè)面間的錨鏈接
3.2 頁(yè)面內(nèi)的錨鏈接
步驟:
3.3 頁(yè)面間的錨鏈接
4.功能鏈接
5.URL
5.1 簡(jiǎn)介
URL:Uniform Resource Locator 統(tǒng)一資源定位器,用來定位資源所在的位置,最常見的就是網(wǎng)址
5.2 組成
一個(gè)完整的URL由8個(gè)部分組成:
協(xié)議:prococol 如 http:超文本傳輸協(xié)議,用來訪問WEB網(wǎng)站Hyper text Transfer protocal https:更加安全的協(xié)議 SSL安全套接子層 ftp文件傳輸協(xié)議,用來訪問服務(wù)器上的文件,實(shí)現(xiàn)文件的上傳和下載File Transfer protocol file:文件協(xié)議,用來訪問本地文件 主機(jī)名hostname服務(wù)器地址或服務(wù)器Netbios名稱,如www.baidu.com ftp://10.255.254.254 端口:port位于主機(jī)名的后面,使用冒號(hào)進(jìn)行分隔 不同的協(xié)議使用不同的端口,如http使用80端口,https使用的443端口,ftp使用20和21 如果使用的是默認(rèn)端口,則端口可以省略 如果使用的不是默認(rèn)端口,則必須指定端口http://59.49.32.213:7070/ 路徑:path目標(biāo)文件所在的路徑結(jié)構(gòu),如:www.baidu.com/img/ 資源resource要訪問的目標(biāo)文件,如bd_logo1.png 查詢字符串:query string 也稱為參數(shù) 在資源后面使用?開頭的一組名稱/值
鏈接文本
鏈接文本
https://www.baidu.com/img/bd_logo1.png?name=tom&age=2&sex=male https://www.w3school.com.cn/html/html_quotation_elements.asp file:///C:/Users/Administrator/Desktop/project/code/09.%E5%B8%B8%E7%94%A8%E6%A0%87%E7%A D%BE3.html http://www.sxgjpx.net/ ftp://10.255.254.253/
1
1
1 2 3
4 5
名稱和值之間以=分隔,多個(gè)之間用&分隔,如:name=tom&age=2&sex=male 錨點(diǎn)anchor,在資源后面使用#開頭的文本,如#6 身份認(rèn)證authentication,指定身份信息,如:ftp://賬戶:密碼@ftp.bbshh010.com
五、表格
1.簡(jiǎn)介
表格是一個(gè)規(guī)則的行列結(jié)構(gòu),每個(gè)表格是由若干行組成,每行由若干個(gè)單元格組成
table row column
2.基本結(jié)構(gòu)
2.1 table標(biāo)簽
用來定義表格
常用屬性:
border:表格邊框 默認(rèn)為0 width/height:寬度/高度 bordercolor:邊框的顏色 align:對(duì)齊方式,取值:left(默認(rèn)) center居中 right居右 bgcolor:背景顏色 background:背景圖片 cellspacing間距:?jiǎn)卧衽c單元格之間的距離 cellpadding邊距:?jiǎn)卧裰械膬?nèi)容到邊界之間的距離
2.2 tr標(biāo)簽
用來定義行:table row
常用屬性:
align:水平對(duì)齊 取值:left(默認(rèn)) center right valign垂直對(duì)齊 取值:top center bottom bgcolor:背景顏色 background:背景圖片
2.3 td標(biāo)簽
用來定義單元格,table data
常用屬性:align、valign、bgcolor、background
注意:表格必須是由行組成,行必須由單元格來組成,數(shù)據(jù)必須放到單元格中
3.合并單元格
合并單元格也稱為單元格的跨行跨列
兩個(gè)屬性:
rowspan 設(shè)置單元格所跨的行數(shù) colspan 設(shè)置單元格所跨的列數(shù)
步驟:
六、表單
1.簡(jiǎn)介
表單是一個(gè)包含若干個(gè)表單元素的區(qū)域,用于獲取瑣類型的用戶數(shù)據(jù)
表單元素是允許用戶在表單輸入信息的元素,如文本框、密碼框、單選按鈕、復(fù)選框、下拉列表、按鈕等
2.表單結(jié)構(gòu)
2.1表單語法
1
2.2form標(biāo)簽
用來定義表單,可以包含多個(gè)表單元素
常用屬性:
action:提交數(shù)據(jù)給誰處理,即處理數(shù)據(jù)的程序,默認(rèn)為當(dāng)前頁(yè)面 method:提交數(shù)據(jù)的方式或方法,取值:get(默認(rèn)),post get和post的區(qū)別: get:以查詢字符串的形式提交,在地址欄中能看到,長(zhǎng)度有限制,不安全 post以表單數(shù)據(jù)組的形式進(jìn)行提交,在地址欄中看不到,長(zhǎng)度無限制,安全 enctype(encode type)編碼類型:提交數(shù)據(jù)的編碼,取值:application/X-www-form-urlencoded(默 認(rèn))、multipart/form-data(文件上傳)
3.表單元素
大多數(shù)的表單元素都是使用 標(biāo)簽來定義的,通過設(shè)置屬性type來定義不同的表單元素
1
3.1單行文本框
常用屬性:
·name名稱,很重要,如果沒有定義name屬性,則該表單元素的數(shù)據(jù)是無法提交的
·value初始值
·size顯示寬度
·maxlength:大字符數(shù),默認(rèn)是沒有限制
·readonly只讀:readonly=“readonly”,可簡(jiǎn)寫readonly,即只寫屬性名
·disabled禁用:disabled=“disabled”, 可簡(jiǎn)寫disabled完全禁用
表單元素被提交的兩個(gè)條件,1.有name屬性2.非disabled
3.2 單選按鈕
常用屬性:
·name名稱:多個(gè)radio的name屬性必須相同,才能實(shí)現(xiàn)互斥(單選)
·value值
·checked:是否被選中,兩種狀態(tài),選中,未選中 checked=“checked” 簡(jiǎn)寫 checked
3.3 復(fù)選框
常用屬性與單選按鈕radio類似
3.4 文件選擇器
常用屬性:
·name:名稱
·accept設(shè)置可選擇的文件類型,用來限制上傳的文件類型
使用MIME格式字符串對(duì)資源類型進(jìn)行限制
常見的MIME類型:
·純文本:text/plain text/xml text/html
· 圖像:image/png image/jpeg image/gif
4.特殊表單元素
4.1下拉列表
select常用屬性:
·name名稱
·size行數(shù),同時(shí)顯示多個(gè)選項(xiàng)
·multiple允許同時(shí)選擇多個(gè)
option常用屬性:
·value選項(xiàng)值
·selected設(shè)置默認(rèn)選中項(xiàng)
optgroup常用屬性:
·label分組的標(biāo)簽
4.2文本域
·name名稱
·rows行數(shù)
·cols列數(shù)
5、其他標(biāo)簽
5.1 label標(biāo)簽
為表單元素提供標(biāo)簽,當(dāng)選中l(wèi)abel標(biāo)簽中的文本內(nèi)容時(shí)會(huì)自動(dòng)將光標(biāo)切換到與之相關(guān)聯(lián)的表單元素。
常用屬性:
·for必須將該屬性值設(shè)置為與相關(guān)聯(lián)的表單元素的Id屬性值相同。
注:幾乎所有HTML標(biāo)簽都具有id屬性,且id值必須唯一。
5.2 button標(biāo)簽
也表示按鈕,與input按鈕類似
語法:
1按鈕文字或圖像
常用屬性:
·type按鈕的類型,取值: submit(默認(rèn))、reset、button
5.3 fieldset和legend標(biāo)簽
fieldset標(biāo)簽,對(duì)表單元素進(jìn)行分組
legend標(biāo)簽,對(duì)分組添加標(biāo)題
七、內(nèi)嵌框架
1、簡(jiǎn)介
使用iframe可以在一個(gè)頁(yè)面中引用另一個(gè)頁(yè)面,實(shí)現(xiàn)復(fù)用、靈活
2、基本用法
語法:
1
常用屬性:
· src:引用的頁(yè)面
· width/height寬度/高度 ,像素或百分比
· frameborder是否顯示邊框,取值:1(yes) 0(no)—默認(rèn)
· scrolling是否顯示滾動(dòng)條,取值:yes no auto
· name屬性 為框架定義名稱
3、在框架中打開鏈接
1
2
3鏈接的文本或圖像
八、HTML5簡(jiǎn)介
1、發(fā)展
W3C于1992年12月發(fā)布了HTML4.0.1標(biāo)準(zhǔn)
W3C于2014年10月發(fā)布了HTML5標(biāo)準(zhǔn)
2、特點(diǎn)
· 取消了過時(shí)的標(biāo)簽,如font、center等,它們僅具有展示外觀的功能
· 增加了一些更具有語義化的標(biāo)簽,如header、footer、aside等
· 增加了一些新功能標(biāo)簽,如canvas、audio、video
· 增加了一些表單控件,如email、date、time、url、search等
· 可以直接在瀏覽器中繪畫(canvas),無需flash
· 增加了本地存儲(chǔ)的支持
3、兼容性
http://caniuse.com
提供了各種瀏覽器版本對(duì)HTML5和CSS規(guī)范的支持度
九、HTML5新增內(nèi)容
1、結(jié)構(gòu)相關(guān)的標(biāo)簽
用來進(jìn)行頁(yè)面結(jié)構(gòu)布局,本身無任何特殊樣式,需要使用CSS進(jìn)行樣式設(shè)置
· article定義一個(gè)獨(dú)立的內(nèi)容,完整的文章
· section定義文檔的章節(jié)、段落
· header文章的頭部、頁(yè)眉、標(biāo)題
· footer文章的底部、頁(yè)腳、標(biāo)注
· aside定義側(cè)邊欄
· figure圖片區(qū)域
· figcaption為圖片區(qū)域定義標(biāo)題
· nav定義導(dǎo)航菜單
結(jié)構(gòu)標(biāo)簽只是表明各部分的角色,并無實(shí)際的外觀樣式,與普通div相同
2、語義相關(guān)的標(biāo)簽
2.1 mark標(biāo)簽
標(biāo)注,用來突出顯示文本,默認(rèn)添加黃色背景
2.2 time標(biāo)簽
定義日期和時(shí)間,便于搜索引擎智能查找
2.3 details和 summary標(biāo)簽
默認(rèn)顯示summary中的內(nèi)容,點(diǎn)擊后顯示details中的內(nèi)容
注:并不是所有的瀏覽器都兼容,chrome、opera支持、Firefox、IE瀏覽器不支持
2.4 meter標(biāo)簽
計(jì)數(shù)儀,表示度量
常用屬性:
· max定義大值,默認(rèn)為1
· min定義小值,默認(rèn)為0
· value定義當(dāng)前值
· high定義限定為高的值
· low定義限定為低的值
· optimum定義佳值
規(guī)則:
當(dāng)value大于high時(shí)為綠色
當(dāng)value在low與high之間時(shí)為黃色
當(dāng)value小于low時(shí)為紅色
當(dāng)value小于low時(shí)為綠色
當(dāng)value在low與high之間時(shí)為黃色
當(dāng)value大于high時(shí)為紅色
2.5 progress標(biāo)簽
進(jìn)度條,表示運(yùn)行中的進(jìn)度
常用屬性:
· value定義當(dāng)前值
· max定義完成的值
3.表單相關(guān)
3.1 新增表單元素
新增以下type類型:
· email接收郵箱
· url接收URL
· tel接收電話號(hào)碼,目前僅在移動(dòng)設(shè)備上有效
· search搜索文框
· number/range接收數(shù)字/數(shù)字滑塊,包含min,max,step屬性
· date/month/week/time/datetime日期時(shí)間選擇器,兼容性不好
· color顏色拾取
作用:
· 具有格式校驗(yàn)的功能
· 可以與移動(dòng)設(shè)備的鍵盤相關(guān)聯(lián)
3.2新增表單屬性
form標(biāo)簽的屬性:
· autocomplete是否啟動(dòng)表單的自動(dòng)完成功能, 取值:on(默認(rèn))、o?
· novalidate提交表單時(shí)不進(jìn)行校驗(yàn),默認(rèn)會(huì)進(jìn)行表單校驗(yàn)
3.3 新增表單元素的屬性
新增表單元素屬性:input/select/textarea等
· placeholder提示文字
· required是否必填
· autocomplete是否啟用該表單元素的自動(dòng)完成功能
· autofocus設(shè)置初始焦點(diǎn)元素
· pattern使用正則表達(dá)式(RegExp后面會(huì)講解),進(jìn)行數(shù)據(jù)校驗(yàn)
· list使文本元素具有下拉列表的功能,需要配合datalist和option標(biāo)簽一起使用
· form可以將表單元素寫在form標(biāo)簽外面,然后通過該屬性關(guān)聯(lián)指定的表單
4、多媒體標(biāo)簽
4.1audio標(biāo)簽
在頁(yè)面中插入音頻,不同的瀏覽器對(duì)音頻格式的支持不一樣
audio常用屬性:
· src音頻文件的來源
· controls是否顯示控制面板,默認(rèn)不顯示
· autoplay是否自動(dòng)播放,默認(rèn)不自動(dòng)播放
· loop是否循環(huán)播放
· muted是否靜音
· preload是否預(yù)加載,取值:none不預(yù)加載、auto預(yù)加載(默認(rèn))、metadata只加載元數(shù)據(jù)
如果設(shè)置了autoplay屬性,則該屬性無效
可以結(jié)合source標(biāo)簽使用,指定多個(gè)音頻文,瀏覽器會(huì)檢測(cè)并使用第一個(gè)可用的音頻文件
4.2 video標(biāo)簽
在頁(yè)面中插入視頻,不同的瀏覽器對(duì)視頻格式的支持不一樣
用法與audio標(biāo)簽基本相同,增加屬性:
· widht/height視頻播放器的寬度/高度
· poster在視頻加載前顯示的圖片
<html>
<body>
<tiele>HTML技術(shù)</tiele>
</body>
<body>
大家好,歡迎學(xué)習(xí)html技術(shù)!
</body>
</html>1234567
效果
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-h271e4v6-1593240920352)(C:\Users\lenovo\Desktop\新建文件夾\靜態(tài)網(wǎng)頁(yè)2\案例\result\案例1.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>標(biāo)簽</title>
</head>
<body text="blue">
標(biāo)簽的組成
<br>
html從入門到精通!
<hr>
<h1>標(biāo)簽的分類</h1>
<hr>
<h2>標(biāo)簽的分類</h2>
<hr>
<h6>標(biāo)簽的分類</h6>
<hr>
<span>哈哈</span>嘿嘿
</body>
</html>1234567891011121314151617181920212223
效果
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-jx6zJE1P-1593240920354)(C:\Users\lenovo\Desktop\新建文件夾\靜態(tài)網(wǎng)頁(yè)2\案例\result\案例2.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
圖書:<<HTML從入門到精通<<
<hr>
北京 上海 廣州
<hr>
在HTML中用<表示<小于號(hào)
<hr>
“HTML語言” 或 &qout;HTML語言&qout;
<hr>
版權(quán)所有? 2000-2020 高教培訓(xùn)
<hr>
×關(guān)閉符號(hào)
</body>
</html>123456789101112131415161718192021222324
效果
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-nuFLl3hm-1593240920355)(C:\Users\lenovo\Desktop\新建文件夾\靜態(tài)網(wǎng)頁(yè)2\案例\result\案例3.png)]
(剩下的下期出)
原文鏈接:https://blog.csdn.net/WanXuang/article/details/106982782?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160513384519724835852804%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160513384519724835852804&biz_id=&utm_medium=distribute.pc_search_top_result.none-task-code-2~all~top_position~default-1-106982782-12.nonecase&utm_term=html
作者:WanXuang
出處:從CSDN
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。