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 亚洲男人第一天堂,色妞永久免费视频,九一精品国产

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          第69節(jié) 跨域請(qǐng)求-Web前端開發(fā)之JavaScript-零點(diǎn)程序員-王唯

          域請(qǐng)求:

          現(xiàn)代的所有的瀏覽器都遵守同源策略,所謂的源指的就是一個(gè)域名、一個(gè)服務(wù)器,同源是指兩個(gè)腳本擁有相同的域名,不同源指的是不同的域名,同源策略指的是,一個(gè)源的腳本不能讀取或操作其他源的http響應(yīng)和cookie,也就是出于安全方面的考慮,頁(yè)面中的JavaScript無法訪問其他服務(wù)器上的數(shù)據(jù),這就是所謂的“同源策略”。
          同源是指協(xié)議、域名和端口都一致。

          不同源限制的內(nèi)容:

          • Cookie、LocalStorge、IndexedDb等存儲(chǔ)性內(nèi)容;
          • DOM節(jié)點(diǎn);
          • Ajax請(qǐng)求;

          跨域請(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ā)送下列頭部:

          • Origin:與簡(jiǎn)單的請(qǐng)求相同;
          • Access-Control-Request-Method:請(qǐng)求自身使用的方法;
          • Access-Control-Request-Headers:(可選)自定義的頭部信息,多個(gè)頭部以逗號(hào)分隔;

          以下是一個(gè)帶有自定義頭部customHeader,并使用POST方法發(fā)送的數(shù)據(jù),如:

          • Origin: http://www.zeronetwork.cn
          • Access-Control-Request-Method: POST
          • Access-Control-Request-Headers: customHeader

          發(fā)送這個(gè)請(qǐng)求后,服務(wù)器端可以決定是否允許這種類型的請(qǐng)求,其通過在響應(yīng)中發(fā)送如下頭部與瀏覽器進(jìn)行溝通:

          • Access-Control-Allow-Origin:與簡(jiǎn)單的請(qǐng)求相同;
          • Access-Control-Allow-Methods:允許的方法,多個(gè)方法以逗號(hào)分隔;
          • Access-Control-Allow-Headers:允許的頭部,多個(gè)頭部以逗號(hào)分隔;
          • Access-Control-Max-Age:應(yīng)該將這個(gè)Preflight請(qǐng)求緩存多長(zhǎng)時(shí)間(以秒表示)

          例如,允許任何源、POST請(qǐng)求方式、自定義頭customHeader以及請(qǐng)求的緩存時(shí)間:

          • Access-Control-Allow-Origin: https://www.zeronetwork.cn
          • Access-Control-Allow-Methods: POST
          • Access-Control-Allow-Headers: customHeader
          • Access-Control-Max-Age: 1728000

          如:

          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是從其他域中加載代碼執(zhí)行,如果其他域不安全,很可能會(huì)在響應(yīng)中夾帶一些惡意代碼;因此在使用不是你自己運(yùn)維的Web服務(wù)時(shí),一定得保證它安全可靠;
          • 其次,只能進(jìn)行GET請(qǐng)求;
          • 最后,要確定JSONP請(qǐng)求是否失敗比較麻煩,雖然HTML5給<script>元素新增了一個(gè)onerror事件處理程序,但目前還沒有得到任何瀏覽器支持;

          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)景是:

          • 頁(yè)面和其打開的新窗口的數(shù)據(jù)傳遞;
          • 多窗口之間消息傳遞;
          • 頁(yè)面與嵌套的iframe消息傳遞;

          一個(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]);

          • otherWindow為其他窗口的一個(gè)引用;
          • message參數(shù):將要發(fā)送到其他window的數(shù)據(jù);它將會(huì)被結(jié)構(gòu)化克隆算法序列化,即可以不受限制的將數(shù)據(jù)對(duì)象安全的傳送給目標(biāo)窗口而無需自己序列化;
          • targetOrigin:通過窗口的origin屬性來指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示無限制)或者一個(gè)URI;
          • transfer參數(shù):可選,是一串和message同時(shí)傳遞的Transferable對(duì)象,這些對(duì)象的所有權(quán)將被轉(zhuǎn)移給消息的接收方,而發(fā)送一方將不再保有所有權(quán);

          例如: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ì)象接收的消息;
          屬性:

          • data屬性:其保存著由發(fā)送者發(fā)送的字符串?dāng)?shù)據(jù);
          • lastEventId屬性:表示事件的唯一ID;
          • origin屬性:返回一個(gè)表示消息發(fā)送者來源;
          • ports屬性:MessagePort對(duì)象數(shù)組,表示消息正通過特定通道(數(shù)據(jù)通道)發(fā)送的相關(guān)端口;
          • source屬性:是一個(gè)MessageEventSource對(duì)象,代表消息發(fā)送者;
          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簡(jiǎn)介

          1.HTML是什么?

          HTML:htper text markup language超文本標(biāo)記(標(biāo)簽)語言

          由各種標(biāo)簽組成,用來制作網(wǎng)頁(yè),告訴瀏覽器如何顯示頁(yè)面

          2.作用

          • 制作網(wǎng)頁(yè),控制網(wǎng)頁(yè)和內(nèi)容的顯示
          • 插入圖片、音樂、視頻、動(dòng)畫等多媒體
          • 通過鏈接來檢索信息
          • 使用表單獲取用戶的信息,實(shí)現(xiàn)交互

          3.版本

          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

          4.擴(kuò)展名

          HTML文檔是以.html或.htm結(jié)尾

          二、HTML文檔結(jié)構(gòu)

          1.基本結(jié)構(gòu)

          1.1簡(jiǎn)介

          • HTML標(biāo)簽是由尖括號(hào)括起來的關(guān)鍵詞,如,通常是成對(duì)出現(xiàn)的,如<html></html>
          • <html>為根標(biāo)簽,包含: <head>頭部和<body>主體部分
          • 頭部提供關(guān)于網(wǎng)頁(yè)的相關(guān)信息,如標(biāo)題、文檔類型、字符編碼、關(guān)鍵字等摘要信息
          • 主體部分提供網(wǎng)頁(yè)的顯示內(nèi)容,真正顯示在頁(yè)面中的內(nèi)容
          • 合理地進(jìn)行縮進(jìn)
          • 標(biāo)簽名不區(qū)分大小寫,但是一般要用小寫

          1.2.開發(fā)工具

          記事本notepad、sublime、Notepad++、Dreamweaver、VScode、Webstorm等

          使用步驟:

          1. 新建文件(cltr+N),然后保存(ctrl+s),指定擴(kuò)展名為.html
          2. 編寫HTML代碼
          3. 在瀏覽器中打開文件

          使用技巧:

          • 先保存再寫代碼,否則代碼無顏色提示
          • 創(chuàng)建一個(gè)文件夾,用于保存所有的網(wǎng)頁(yè)內(nèi)容,將文件夾拖拽到sublime中,便于管理
          • 顯示/隱藏側(cè)邊欄方式1:查看–>側(cè)邊欄–>顯示/隱藏側(cè)邊欄方式2:ctrl+K緊接著按B
          • 顯示多欄方式1:查看–>布局–>列數(shù):2列方式2:Alt+shift+2

          1.3瀏覽器

          常見的瀏覽器:IE瀏覽器微軟、chrome谷歌瀏覽器、fifirefox火狐、safari蘋果

          瀏覽器的作用是讀取html文件,并以網(wǎng)頁(yè)的形式來顯示

          瀏覽器不會(huì)直接顯示html標(biāo)簽,而是使用標(biāo)簽來解釋網(wǎng)頁(yè)的內(nèi)容

          2.標(biāo)簽

          2.1標(biāo)簽的組成

          一個(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)

          2.2標(biāo)簽的分類

          根據(jù)標(biāo)簽是否關(guān)閉,分為,關(guān)閉型和非關(guān)閉型

          • 關(guān)閉型:有結(jié)束標(biāo)簽,即標(biāo)簽成對(duì)出現(xià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>

          2.3注釋

          注釋在瀏覽器中不會(huì)顯示,是用來標(biāo)注解釋html語句,但通過查看源代碼的方式可以看到

          語法:

          <--注釋內(nèi)容-->

          2.4實(shí)體字符

          也稱為特殊字符,用于顯示一些特殊符號(hào),如<>&空格等

          語法:

          <&實(shí)體字符的名稱>

          2.5文檔類型

          在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

          三\常用標(biāo)簽

          3.1基本標(biāo)簽

          • 塊級(jí)標(biāo)簽\親啊后有明顯的間隔 |
            | h1…h(huán)5 | 標(biāo)題標(biāo)簽 | 按照h1到h6逐漸變小.塊級(jí)標(biāo)簽 |
            | | | |
            | | | |


          • 三、常用標(biāo)簽

          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)的錨鏈接
          步驟:

          1. 定義錨點(diǎn)(標(biāo)記)
          2. 鏈接錨點(diǎn)
            _self 自身,當(dāng)前,默認(rèn)值 _blank新的,空白的 _parent父層框架 _top頂層框架
            目標(biāo)位置
            1 2 3 4
            1

          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. 在跨越的單元格中設(shè)置rowspan/colspan屬性 2. 將被跨越的單元格刪除
            必須要保證每行的實(shí)際列數(shù)是相同的,否則表格可能會(huì)出錯(cuò)亂
            4.高級(jí)標(biāo)簽
            4.1caption標(biāo)簽
            表格的標(biāo)題標(biāo)簽
            4.2thead標(biāo)簽
            表格的頭部table head
            4.3th標(biāo)簽
            表格的頭部標(biāo)題table head title
            一般用在thead中,設(shè)置頭部的標(biāo)題,替代td標(biāo)簽,與td的區(qū)別,th中的文本會(huì)加粗且居中顯示
            4.4tbody標(biāo)簽
            表格的主體table body
            4.5tfoot標(biāo)簽
            表格的底部table foot




          六、表單
          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ī)則:

          1. 如果optimum大于high,則表示值越大越好

          當(dāng)value大于high時(shí)為綠色

          當(dāng)value在low與high之間時(shí)為黃色

          當(dāng)value小于low時(shí)為紅色

          1. 如果optimum小于low,則表示值越小越好

          當(dāng)value小于low時(shí)為綠色

          當(dāng)value在low與high之間時(shí)為黃色

          當(dāng)value大于high時(shí)為紅色

          1. 當(dāng)optimum介于low和high之間,則表示值在low和high之間好當(dāng)value在low與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在視頻加載前顯示的圖片

          案例1hello.html

          <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)]

          案例2標(biāo)簽的組成.html

          <!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)]

          案例3實(shí)體字符.html

          <!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


          主站蜘蛛池模板: 一区二区三区无码被窝影院| 亚洲AV日韩AV天堂一区二区三区| 中文字幕一区二区区免| 国模无码一区二区三区不卡| 中日av乱码一区二区三区乱码| 国产免费一区二区三区免费视频| 国产伦精品一区二区免费| 国产在线一区二区| 免费一本色道久久一区| 日韩av片无码一区二区三区不卡 | 国产在线步兵一区二区三区| 国产一区二区内射最近更新| 日本在线视频一区二区| 精品少妇一区二区三区在线| 中文字幕人妻第一区| 无码人妻品一区二区三区精99 | 亚洲AV福利天堂一区二区三| 日本高清一区二区三区 | 久久精品视频一区二区三区| 国产一区二区三区内射高清| 国产福利微拍精品一区二区| 国模精品一区二区三区| 农村人乱弄一区二区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 国精产品一区一区三区| 成人无码一区二区三区| 日韩AV在线不卡一区二区三区| 国产香蕉一区二区三区在线视频 | 国产成人精品一区二区三区免费 | 亚洲综合无码一区二区痴汉| 性无码一区二区三区在线观看| 一区二区在线视频观看| 怡红院一区二区在线观看| 日韩精品一区二区三区中文3d| 亚洲欧美日韩一区二区三区在线| 亚洲国产精品一区二区成人片国内 | 中文字幕一区一区三区| 亚洲一区二区三区不卡在线播放| 精品无码国产一区二区三区51安| 毛片一区二区三区| 精品中文字幕一区二区三区四区|