中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

傳奇世界網(wǎng)頁(yè)版在線玩唐山seo優(yōu)化

傳奇世界網(wǎng)頁(yè)版在線玩,唐山seo優(yōu)化,微網(wǎng)站開發(fā)一般費(fèi)用多少錢,上海企業(yè)網(wǎng)站建設(shè)哪家好day-122-one-hundred-and-twenty-two-20230728-跨域-模塊化-webpack初步 跨域 跨域 為什么要跨域? 瀏覽器為了安全,不能讓我們的html文件可以隨意引用別的服務(wù)器中的文件,只允許我們的html或js文件中,請(qǐng)求我們自己服務(wù)器。這個(gè)…

day-122-one-hundred-and-twenty-two-20230728-跨域-模塊化-webpack初步

跨域

  • 跨域
  1. 為什么要跨域?
    • 瀏覽器為了安全,不能讓我們的html文件可以隨意引用別的服務(wù)器中的文件,只允許我們的html或js文件中,請(qǐng)求我們自己服務(wù)器。這個(gè)就是瀏覽器的同源策略。
    • 因?yàn)槲覀兊木W(wǎng)頁(yè)是一個(gè)html文件,這個(gè)html是在一個(gè)域名里的。而這個(gè)html會(huì)引用各種文件,如圖片、js文件、css文件,這些文件,有時(shí)候并不在一個(gè)服務(wù)器里。
    • 所以我們就需要去到其它服務(wù)器中查找這些文件。
  2. 跨域的方案有:
    1. CORS-跨源資源共享方案
    2. JSONP帶填充的json方案

CORS

  1. CORS 是一種官方的跨域解決方案,通過在服務(wù)器端添加一些 HTTP 頭信息來告訴瀏覽器,允許哪些網(wǎng)站可以訪問這些資源。

CORS針對(duì)get請(qǐng)求

  • fang/f20230728/f20230728/1.get.html 前端要寫的代碼。

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>get - http://127.0.0.1:5500/</title></head><body>請(qǐng)求體 - http://127.0.0.1:5500/</body><script>let xhr = new XMLHttpRequest();xhr.open("GET", "http://localhost:8080", true);xhr.onload = () => {console.log(`接收到的返回體: xhr.responseText-->`, xhr.responseText); //報(bào)錯(cuò): Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.};xhr.send();</script>
    </html>
    
  • fang/f20230728/f20230728/1.server.js 后端要寫的代碼。

    const http = require('http')
    http.createServer((req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')res.end('from: http://localhost:8080')
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

CORS針對(duì)post請(qǐng)求

  • fang/f20230728/f20230728/2.post.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>http://127.0.0.1:5500/</title></head><body>請(qǐng)求體 - http://127.0.0.1:5500/</body><script>let xhr = new XMLHttpRequest();xhr.open("POST", "http://localhost:8080/users", true);xhr.setRequestHeader("Content-Type", "application/json");xhr.onload = () => {console.log(`接收到的返回體: xhr.responseText-->`, xhr.responseText); //報(bào)錯(cuò): Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.};xhr.send(JSON.stringify({ name: "zhufeng1" }));</script>
    </html>
    
  • fang/f20230728/f20230728/2.server.js

    const http = require('http')
    http.createServer((req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')// res.end('from: http://localhost:8080')// Content-Type// res.setHeader('Access-Control-Allow-Headers', 'Content-Type')res.setHeader('Access-Control-Allow-Headers', 'Content-Type');//這個(gè)要在預(yù)檢階段返回。if (req.method === 'OPTIONS') {res.statusCode = 200return res.end()// return res.end('OPTIONS預(yù)檢成功')}if (req.url === '/') {res.end('home')} else if (req.url === '/users') {switch (req.method) {case 'GET': res.end('users')breakcase 'POST': res.end('POST: users')breakdefault:res.end('404')break}}
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

CORS針對(duì)put請(qǐng)求

  • fang/f20230728/f20230728/3.put.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>http://127.0.0.1:5500/</title></head><body>請(qǐng)求體 - http://127.0.0.1:5500/</body><script>let xhr = new XMLHttpRequest();xhr.open("PUT", "http://localhost:8080/users", true);xhr.setRequestHeader("Content-Type", "application/json");xhr.onload = () => {console.log(`接收到的返回體: xhr.responseText-->`, xhr.responseText); //報(bào)錯(cuò): Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.};xhr.send(JSON.stringify({ name: "zhufeng1" }));</script>
    </html>
    
  • fang/f20230728/f20230728/3.server.js

    const http = require('http')
    http.createServer((req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')// res.end('from: http://localhost:8080')// Content-Type// res.setHeader('Access-Control-Allow-Headers', 'Content-Type')res.setHeader('Access-Control-Allow-Headers', 'Content-Type');//這個(gè)要在預(yù)檢階段返回。res.setHeader('Access-Control-Allow-Methods', 'PUT');//這個(gè)要在預(yù)檢階段返回。if (req.method === 'OPTIONS') {res.statusCode = 200return res.end()// return res.end('OPTIONS預(yù)檢成功')}if (req.url === '/') {res.end('home')} else if (req.url === '/users') {switch (req.method) {case 'GET': res.end('GET: users')breakcase 'POST': res.end('POST: users')breakcase 'PUT': res.end('PUT: users')breakdefault:res.end('404')break}} else {res.statusCode = 400res.end()}
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

CORS針對(duì)Cookie

  • fang/f20230728/f20230728/4.visit.html

    <!DOCTYPE html><head><title>get - http://127.0.0.1:5500/</title></head><body>請(qǐng)求體 - http://127.0.0.1:5500/</body><script>let xhr = new XMLHttpRequest();xhr.withCredentials='include'xhr.open("GET", "http://127.0.0.1:8080/visit", true);// xhr.open("GET", "http://localhost:8080/visit", true);xhr.onload = () => {console.log(`接收到的返回體: xhr.responseText-->`, xhr.responseText);};xhr.send();</script>
    </html>
    
  • fang/f20230728/f20230728/4.server.js

    const http = require('http')
    http.createServer((req, res) => {res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')// res.end('from: http://localhost:8080')// Content-Type// res.setHeader('Access-Control-Allow-Headers', 'Content-Type')res.setHeader('Access-Control-Allow-Headers', 'Content-Type');//這個(gè)要在預(yù)檢階段返回。res.setHeader('Access-Control-Allow-Methods', 'PUT');//這個(gè)要在預(yù)檢階段返回。res.setHeader('Access-Control-Allow-Credentials', 'true')if (req.method === 'OPTIONS') {res.statusCode = 200return res.end()// return res.end('OPTIONS預(yù)檢成功')}if (req.url === '/') {res.end('home')} else if (req.url === '/users') {switch (req.method) {case 'GET': res.end('GET: users')breakcase 'POST': res.end('POST: users')breakcase 'PUT': res.end('PUT: users')breakdefault:res.end('404')break}} else if (req.url === '/visit') {const cookies = req.headers.cookielet visit = 0if (cookies) {let items = cookies.split(/;\s+/)for (let i = 0; i < items.length; i++) {let item = items[i]let [key, value] = item.split('=')if (key === 'visit') {visit = Number(value)break}}}visit++res.setHeader('Set-Cookie', [`visit=${visit}; SameSite=None; Secure=false`])res.end(`${visit}`)} else {res.statusCode = 400res.end()}
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

CORS詳細(xì)說明

  • fang/f20230728/3.cors/1.server.js
//1.引入node.js內(nèi)置用來創(chuàng)建 http服務(wù)器的模塊
const http = require('http');
//2.創(chuàng)建http服務(wù)器,指定請(qǐng)求處理函數(shù),以后每當(dāng)有客戶端請(qǐng)求到達(dá)服務(wù)器的時(shí)候就會(huì)由此
//請(qǐng)求處理函數(shù)來處理請(qǐng)求,并返回響應(yīng)
//req代表請(qǐng)求對(duì)象,如果 想獲取請(qǐng)求信息比如請(qǐng)求行 METHOD url 請(qǐng)求頭 請(qǐng)求體可以使用此對(duì)象
//res代表響應(yīng)對(duì)象,如果想寫入響應(yīng)信息,比如狀態(tài)碼 響應(yīng)頭 響應(yīng)體使用此對(duì)象 
http.createServer((req, res) => {//服務(wù)器返回一個(gè)響應(yīng)頭,以后如果是來自于5500的訪問,則瀏覽器不會(huì)再進(jìn)行阻止res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500');//在預(yù)覽的時(shí)候,需要返回響應(yīng)頭res.setHeader('Access-Control-Allow-Headers', 'Content-Type');//在預(yù)檢的時(shí)候,需要返回響應(yīng)頭Allow-Methods,它的值就是允許跨域請(qǐng)求的方法res.setHeader('Access-Control-Allow-Methods', 'PUT');//允許跨域的時(shí)候攜帶cookieres.setHeader('Access-Control-Allow-Credentials', 'true')//如果客戶端發(fā)送過來的是一個(gè)OPTIONS請(qǐng)求的話,說明客戶端只是需要確認(rèn)一下是否允許跨域//它需要判斷是否有Access-Control-Allow-Origin就可以了,不需要響應(yīng)體if (req.method === 'OPTIONS') {res.statusCode = 200;return res.end();}if (req.url === '/') {res.end('home');} else if (req.url === '/users') {switch (req.method) {case 'GET':res.end('users');break;case 'POST':res.end('POST /users');break;case 'PUT':res.end('PUT /users');break;default:break;}//當(dāng)客戶端訪問/visit路徑的時(shí)候} else if (req.url === '/visit') {//取出客戶端傳遞過來的cookieconst cookies = req.headers.cookie;console.log('cookies', cookies);//定義一個(gè)客戶端訪問次數(shù)的變量let visit = 0;if (cookies) {// key1=value1;  visit=1;key3=value3//先用分割符把cookie拆成字符串的數(shù)組,然后再循環(huán)此字符串?dāng)?shù)組let items = cookies.split(/;\s+/);for (let i = 0; i < items.length; i++) {//再用=對(duì)每個(gè)cookie進(jìn)行分割,會(huì)返回一個(gè)數(shù)組 1項(xiàng) key 2項(xiàng) valuelet [key, value] = items[i].split('=');if (key === 'visit') {visit = Number(value)break;}}}//讓訪問次數(shù)加1visit++;//服務(wù)器通過響應(yīng)頭Set-Cookie向客戶端種植cookie visit=2//SameSite 是否只允許同域或者說同站點(diǎn)訪問, 只有把它設(shè)置為None才能允許跨域讀寫cookie //Secure為true的話表示只允許在https站點(diǎn)生效res.setHeader('Set-Cookie', [`visit=${visit}; SameSite=None; Secure=false`]);//返回最新的訪問次數(shù)res.end(`${visit}`);} else {res.statusCode = 404;//即使你沒有向客戶端寫入響應(yīng)體,也需要關(guān)閉響應(yīng),//不然客戶端會(huì)一直在等待服務(wù)器的響應(yīng),一直在那里轉(zhuǎn)圈圈 res.end();}
}).listen(8080, () => console.log('8080'));
  • fang/f20230728/3.cors/get.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>//創(chuàng)建Ajax對(duì)象的實(shí)例let xhr = new XMLHttpRequest();//打開連接xhr.open("GET", "http://localhost:8080", true);//指定成功的回調(diào), 等客戶端讀取完響應(yīng)信息后對(duì)執(zhí)行onload回調(diào)函數(shù)xhr.onload = () => {console.log(xhr.responseText);};//發(fā)送請(qǐng)求給服務(wù)器xhr.send();</script></body>
</html>
  • fang/f20230728/3.cors/post.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>//創(chuàng)建Ajax對(duì)象的實(shí)例let xhr = new XMLHttpRequest();//打開連接xhr.open("POST", "http://localhost:8080/users", true);//如果要想發(fā)送請(qǐng)求體,就需要設(shè)置Content-Type請(qǐng)求頭,指定請(qǐng)求體的格式//跨域的時(shí)候發(fā)送一個(gè)請(qǐng)求頭xhr.setRequestHeader("Content-Type", "application/json");//指定成功的回調(diào), 等客戶端讀取完響應(yīng)信息后對(duì)執(zhí)行onload回調(diào)函數(shù)xhr.onload = () => {console.log(xhr.responseText);};xhr.onerror = (onerror) => {console.error(onerror);};//發(fā)送請(qǐng)求給服務(wù)器xhr.send(JSON.stringify({ name: "zhufeng1" }));</script></body>
</html>
  • fang/f20230728/3.cors/put.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>//創(chuàng)建Ajax對(duì)象的實(shí)例let xhr = new XMLHttpRequest();//打開連接xhr.open("PUT", "http://localhost:8080/users", true);//如果要想發(fā)送請(qǐng)求體,就需要設(shè)置Content-Type請(qǐng)求頭,指定請(qǐng)求體的格式//跨域的時(shí)候發(fā)送一個(gè)請(qǐng)求頭xhr.setRequestHeader("Content-Type", "application/json");//指定成功的回調(diào), 等客戶端讀取完響應(yīng)信息后對(duì)執(zhí)行onload回調(diào)函數(shù)xhr.onload = () => {console.log(xhr.responseText);};xhr.onerror = (onerror) => {console.error(onerror);};//發(fā)送請(qǐng)求給服務(wù)器xhr.send(JSON.stringify({ name: "zhufeng1" }));</script></body>
</html>
  • fang/f20230728/3.cors/visit.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>let xhr = new XMLHttpRequest();//withCredentials是XMLHttpRequest的一個(gè)屬性,該屬性定義了是否在請(qǐng)求中攜帶cookie//默認(rèn)情況下此值為 false,這意味著不攜帶cookie,如果true,則攜帶 cookiexhr.withCredentials = "include";xhr.open("GET", "http://127.0.0.1:8080/visit", true);xhr.onload = () => {console.log(xhr.responseText);};xhr.send();</script></body>
</html>

JSONP

靜態(tài)js文件-JSONP原理

  • fang/f20230728/f20230728/6.serve-jsonp.js

    const http = require('http')
    http.createServer((req, res) => {res.setHeader('Content-Type', 'application/javascript')let script = `// 這里是服務(wù)器那邊動(dòng)態(tài)生成的js代碼。console.log('開始執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')getData({'id':100,name:'fang'});console.log('結(jié)束執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')`// res.end(`console.log('from服務(wù)器8080的打印輸出main')`);res.end(script);
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    
  • fang/f20230728/f20230728/6.jsonp.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsonp</title></head><body>靜態(tài)jsonp原理<script>window.getData = function getData(data) {console.log(`data-->`, data);};</script><script src="http://localhost:8080/sugrec.js"></script></body>
    </html>
    

有了一點(diǎn)動(dòng)態(tài)的jsonp

  • fang/f20230728/f20230728/7.jsonp.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsonp</title></head><body>動(dòng)態(tài)jsonp。<script>let callbackName = `JQuery_${Date.now()}`;window[callbackName] = function (data) {console.log(`data-->`, data);};let script = document.createElement("script");script.src = `http://localhost:8080/sugrec.js?cb=${callbackName}`;document.body.appendChild(script);</script></body>
    </html>
    
  • fang/f20230728/f20230728/7.serve-jsonp.js

    const http = require('http')
    const url = require('url')
    http.createServer((req, res) => {res.setHeader('Content-Type', 'application/javascript')const { query: { cb } } = url.parse(req.url || '', true)let script = `// 這里是服務(wù)器那邊動(dòng)態(tài)生成的js代碼。console.log('開始執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')${cb}({'id':100,name:'這個(gè)是后端構(gòu)建出來的json數(shù)據(jù)'});console.log('結(jié)束執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')`res.end(script);
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

動(dòng)態(tài)jsonp

  • fang/f20230728/f20230728/8.jsonp.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsonp</title></head><body>動(dòng)態(tài)jsonp。這里是自動(dòng)生成的`Live Server`起起來的,服務(wù)器端口為5500;<script>let callbackName = `JQuery_${Date.now()}`;console.log(`動(dòng)態(tài)函數(shù)變量名:callbackName-->`, callbackName);window[callbackName] = async (data) => {console.log(`后端返回的json數(shù)據(jù):data-->`, data);await new Promise((resolve, reject) => {setTimeout(() => {resolve("");}, 300000);});// 執(zhí)行結(jié)束后,移除多余代碼。console.log(`執(zhí)行結(jié)束后,移除多余代碼。`);window[callbackName] = null;document.body.removeChild(script);};let script = document.createElement("script");script.src = `http://localhost:8080/sugrec.js?cb=${callbackName}`;console.log(`動(dòng)態(tài)生成的腳本標(biāo)簽:script-->`, script);document.body.appendChild(script);</script></body>
    </html>
    
  • fang/f20230728/f20230728/8.serve-jsonp.js

    // 這里是用node起起來的,服務(wù)器端口為8080;
    const http = require('http')
    const url = require('url')
    http.createServer((req, res) => {res.setHeader('Content-Type', 'application/javascript')const { query: { cb } } = url.parse(req.url || '', true)//這里是為了讓后端拿到前端定義的那個(gè)函數(shù)的函數(shù)名。const jsonObj = { 'id': 100, name: '這個(gè)是后端構(gòu)建出來的json數(shù)據(jù)' }//這個(gè)就是后端要返回的json數(shù)據(jù)。const jsonStr = JSON.stringify(jsonObj)let script = `// 這里是服務(wù)器那邊動(dòng)態(tài)生成的js代碼。console.log('開始執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')${cb}(${jsonStr});console.log('結(jié)束執(zhí)行服務(wù)器返回的動(dòng)態(tài)js代碼。')`res.end(script);
    }).listen(8080, () => {console.log(`服務(wù)器地址為: http://localhost:8080`);
    })
    

jsonP詳細(xì)說明

  • fang/f20230728/3.cors/jsonp.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>//動(dòng)態(tài)創(chuàng)建方法名let callbackName = `jQuery_${Date.now()}`;//動(dòng)態(tài)給window上添加一個(gè)變量,值是一個(gè)函數(shù),并接收一個(gè)數(shù)據(jù)對(duì)象作為參數(shù)window[callbackName] = function (data) {console.log(data);};//動(dòng)態(tài)創(chuàng)建scriptlet script = document.createElement("script");//讓此動(dòng)態(tài)腳本src等于服務(wù)器地址script.src = `http://localhost:8080/sugrec.js?cb=${callbackName}`;//把此動(dòng)態(tài)創(chuàng)建的腳本對(duì)象添加到body上,瀏覽器如果發(fā)現(xiàn)html上多了一個(gè)script標(biāo)簽,//就會(huì)立刻向它的script.src地址發(fā)出請(qǐng)求,并且取回來一段JS代碼,并且立刻執(zhí)行document.body.appendChild(script);</script></body>
</html>
  • fang/f20230728/3.cors/jsonp.js
const http = require('http');
const url = require('url');
http.createServer((req, res) => {//使用url.parse方法解析url地址,并且把查詢 字符串變成一個(gè)query對(duì)象//search=?cb=jQuery_130 query={cb:"jQuery_130"}const {query:{cb}} = url.parse(req.url,true);//告訴客戶端我返回的是一段JS腳本res.setHeader('Content-Type','application/javascript');//創(chuàng)建一段JS腳本字符串let script = `${cb}({"id":100,"name":"zhufeng"})`;//作為響應(yīng)體發(fā)回給客戶端res.end(script);
}).listen(8080, () => console.log('8080'));

jsonp示例-百度功能初步實(shí)現(xiàn)

  • fang/f20230728/f20230728/5.baidu.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsonp-baidu</title></head><body><input type="text" id="search-word" /><ul id="suggestions"></ul></body><script>let $ = {ajax(options) {return new Promise((resolve, reject) => {const { url, jsonp, data } = options;let callbackName = `JQuery_${Date.now()}`;window[callbackName] = function (data) {// console.log(`前端所希望的后端數(shù)據(jù):data-->`, data);resolve(data);};let script = document.createElement("script");script.src = `https://www.baidu.com/sugrec?prod=pc&wd=${data.wd}&cb=${callbackName}`;script.onerror = (error) => reject(error);document.body.appendChild(script);});},};let searchWord = document.getElementById("search-word");let suggestions = document.getElementById("suggestions");searchWord.addEventListener("input", (event) => {let wd = event.target.value;let callbackName = `JQuery_${Date.now()}`;console.log(`wd-->`, wd);console.log(`改:callbackName-->`, callbackName);// https://www.baidu.com/sugrec?prod=pc&wd=a&cb=jQuery_222$.ajax({url: "https://www.baidu.com/sugrec",jsonp: "cb",data: {prod: "pc",wd,},}).then((result) => {console.log(`result-->`, result);let { g } = result;if (g) {let html = ``;for (let i = 0; i < g.length; i++) {html += `<li>${g[i].q}</li>`;}suggestions.innerHTML = html;}}).catch((error) => {console.log(`error-->`, error);});});</script>
</html>

百度下拉項(xiàng)示例-jsonp封裝

  • fang/f20230728/f20230728/9.baidu.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>jsonp-baidu</title></head><body><input type="text" id="search-word" /><ul id="suggestions"></ul></body><script>const jsonpFunction = (options) => {return new Promise((resolve, reject) => {const { url, jsonp, data } = options;const callbackName = `JQuery_${Date.now()}`;window[callbackName] = function (data) {resolve(data);delete window[callbackName];document.body.removeChild(script);};let queryString = url?.indexOf("?") === -1 ? "?" : "&";for (const key in data) {const value = data[key];queryString += `${key}=${value}&`;}let script = document.createElement("script");script.src = `${url}${queryString}&${jsonp}=${callbackName}`;script.onerror = (error) => {reject(error);delete window[callbackName];document.body.removeChild(script);};document.body.appendChild(script);});};let searchWord = document.getElementById("search-word");let suggestions = document.getElementById("suggestions");searchWord.addEventListener("input", (event) => {let wd = event.target.value;let callbackName = `JQuery_${Date.now()}`;console.log(`wd-->`, wd);console.log(`改一:callbackName-->`, callbackName);// https://www.baidu.com/sugrec?prod=pc&wd=a&cb=jQuery_222jsonpFunction({url: "https://www.baidu.com/sugrec",jsonp: "cb",data: {prod: "pc",wd,},}).then((result) => {console.log(`result-->`, result);let { g } = result;if (g) {let html = ``;for (let i = 0; i < g.length; i++) {html += `<li>${g[i].q}</li>`;}suggestions.innerHTML = html;}}).catch((error) => {console.log(`error-->`, error);});});</script>
</html>

純前端的jsonp封裝詳細(xì)說明

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><input id="search-word" /><ul id="suggestions"></ul><script>function jsonp(options) {return new Promise((resolve, reject) => {const { url, jsonp, data } = options;//1.或者創(chuàng)建一個(gè)臨時(shí)的、唯一的方法名let callbackName = `jQuery_${Date.now()}`;//給window添加一個(gè)全局變量,變量名為方法,值是一個(gè)回調(diào)函數(shù)window[callbackName] = function (data) {//一旦此函數(shù)執(zhí)行了,那么此變量則不再需要了,可以刪除銷毀了delete window[callbackName];//此時(shí)script腳本也不再需要,可以刪除掉document.body.removeChild(script);//把data傳遞給了resolve函數(shù),也就是傳遞給了成功的回調(diào)函數(shù)resolve(data);};//動(dòng)態(tài)創(chuàng)建一個(gè)類型為script的對(duì)象或者說元素let script = document.createElement("script");//定義一個(gè)查詢字符串變量//如果url地址里已經(jīng)有問號(hào)了,則用&接著拼接其它的參數(shù),如果沒有?,那就用?開頭let queryStr = url.indexOf("?") === -1 ? "?" : "&";for (let key in data) {// += `prod=pc&`// += `wd=a&`;queryStr += `${key}=${data[key]}&`;}//url=https://www.baidu.com/sugrec//queryStr=?prod=pc&wd=a&//指定script的來源或者說要訪問的腳本的地址script.src = `${url}${queryStr}${jsonp}=${callbackName}`;//src=https://www.baidu.com/sugrec?prod=pc&wd=a&cb=jQuery_130script.onerror = (error) => reject(error);//向body的尾部添加一個(gè)script對(duì)象document.body.appendChild(script);});}//獲取關(guān)鍵字輸入框DOM元素let searchWord = document.getElementById("search-word");//獲取聯(lián)想詞的下拉列表DOM元素let suggestions = document.getElementById("suggestions");//給關(guān)鍵字輸入框綁定輸入事件,當(dāng)用戶在輸入框中輸入字符串執(zhí)行回調(diào)函數(shù)searchWord.addEventListener("input", (event) => {//調(diào)用https://www.baidu.com/sugrec?prod=pc&wd=a&cb=jQuery_222//獲取事件源的值,也就是關(guān)鍵字輸入框的值let wd = event.target.value;jsonp({url: "https://www.baidu.com/sugrec", //你想請(qǐng)求的url地址jsonp: "cb", //最終希望調(diào)用方法名是通過哪個(gè)查詢參數(shù)發(fā)送給服務(wù)器的cb=jQuery_13000data: { prod: "pc", wd }, //其它要傳遞給服務(wù)器的數(shù)據(jù),它們都會(huì)拼接到查詢字符串中}).then((result) => {//獲取結(jié)果中的g屬性let { g } = result;if (g) {let html = "";for (let i = 0; i < g.length; i++) {html += `<li>${g[i].q}</li>`;}suggestions.innerHTML = html;}}).catch((error) => {console.log(error);});});</script></body>
</html>

模塊化

commonJs模塊規(guī)范

  1. 這個(gè)是在nodejs中使用,主要是ES6MOdule沒出來之前。不過它只支持以同步的方式導(dǎo)入一個(gè)模塊。

以對(duì)象屬性的方式單個(gè)導(dǎo)出

  • fang/f20230728/f20230728/commonJs/math1.js 寫模塊的。

    console.log(`模塊內(nèi):exports-->`, exports);
    exports.add = (a, b) => {return a + b
    }
    exports.minus = (a, b) => {return a - b
    }
    
  • fang/f20230728/f20230728/commonJs/use1.js 使用模塊的。

    let math = require('./math1')
    console.log(`使用模塊:math-->`, math);
    console.log(`使用模塊:math.add(1,2)-->`, math.add(1, 2));
    console.log(`使用模塊:math.minus(1,2)-->`, math.minus(1, 2));
    
  • 詳細(xì)說明:

以module.exports的方式全量導(dǎo)出

  • fang/f20230728/f20230728/commonJs/math2.js

    console.log(`模塊內(nèi)2:module-->`, module);
    console.log(`模塊內(nèi)2:module.exports-->`, module.exports);
    module.exports = {add(a, b) {return a + b;},minus(a, b) {return a - b;}
    }
    
  • fang/f20230728/f20230728/commonJs/use2.js

    let math = require('./math2')
    console.log(`使用模塊2:math-->`, math);
    console.log(`使用模塊2:math.add(1,2)-->`, math.add(1, 2));
    console.log(`使用模塊2:math.minus(1,2)-->`, math.minus(1, 2));
    

AMD

AMD單個(gè)引入

  • fang/f20230728/f20230728/AMD/index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script src="https://unpkg.com/requirejs@2.3.6/require.js"></script><script>require(["math"], (math) => {console.log(`單個(gè)引入:math.add(1,2)-->`, math.add(1, 2));});</script></body>
</html>
  • fang/f20230728/f20230728/AMD/math.js
define(function () {//定義此模塊的輸出;return {add(a, b) {return a + b}, minus(a, b) {return a - b}}
});

AMD多個(gè)引入

  • fang/f20230728/f20230728/AMD/index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script src="https://unpkg.com/requirejs@2.3.6/require.js"></script><script>// console.log(`require-->`, require);require(["math"], (math) => {console.log(`單個(gè)引入:math.add(1,2)-->`, math.add(1, 2));});require(["math", "format"], (math, format) => {console.log(`多個(gè)引入:math.add(1, 2)-->`, math.add(1, 2));console.log(`多個(gè)引入:format.print()-->`, format.print());});</script></body>
</html>
  • fang/f20230728/f20230728/AMD/math.js
define(function () {return {add(a, b) {return a + b}, minus(a, b) {return a - b}}
});
  • fang/f20230728/f20230728/AMD/format.js
define(function () {//定義此模塊的輸出return {async print() {console.log('模塊內(nèi)最初執(zhí)行', Date.now())await new Promise((resolve, reject) => {setTimeout(() => {resolve('')}, 4000)})console.log('模塊內(nèi)最后執(zhí)行', Date.now())}}
});

AMD詳細(xì)說明

  • fang/f20230728/4.module/2.amd/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="https://unpkg.com/requirejs@2.3.6/require.js"></script><script>//內(nèi)部會(huì)以異步的方式加載math.js文件,并獲取math.js導(dǎo)出的對(duì)象//異步加載完成后會(huì)執(zhí)行回調(diào)函數(shù),把math.js導(dǎo)出的對(duì)象傳進(jìn)去//require方法接收2個(gè)參數(shù),一個(gè)依賴數(shù)組,一個(gè)是回調(diào)函數(shù)//當(dāng)所有依賴都加載成功后,就會(huì)調(diào)用回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)是依賴模塊的輸出require(['math','format'],(math,format)=>{console.log(math.add(1,2))console.log(format.print())});</script>
</body>
</html>
  • fang/f20230728/4.module/2.amd/format.js
define(function () {//定義此模塊的輸出return {print() {console.log(Date.now())}}
});
  • fang/f20230728/4.module/2.amd/math.js
define(function () {//定義此模塊的輸出return {add(a, b) {return a + b;},minus(a, b) {return a - b;}}
});

ES6Module

  • fang/f20230728/f20230728/ES6Module/math.js

    //單個(gè)導(dǎo)出一個(gè)變量age
    export const age = 16;// export //這個(gè)是一個(gè)關(guān)鍵字,后面只能接變量名或變量聲明。function add(a, b) {return a + b;
    }
    function minus(a, b) {return a - b;
    }
    const obj1 = { a: 6 }
    const msg = 'hello';//批量導(dǎo)出add,minus多個(gè)變量,但也只算是單個(gè)導(dǎo)出,依舊要解構(gòu)才能使用。
    export {add,obj1,// obj2 : 6,//報(bào)錯(cuò)。// let obj2 = 6,//報(bào)錯(cuò)。// obj2 = 6,//報(bào)錯(cuò)。minus,
    }// export { }//這個(gè)是一個(gè)關(guān)鍵字,大括號(hào)內(nèi)部只能寫變量名。
    // 相當(dāng)于語法為: export {變量名1,變量名2,... }//一個(gè)模塊中的默認(rèn)導(dǎo)出只能有一個(gè)
    export default '北京'
    //A module cannot have multiple default exports.
    //export default   '北京'
    
  • fang/f20230728/f20230728/ES6Module/app.js

    import home from './math.js';
    import { age, add, minus, obj1 } from './math.js';
    // import home,{age,add,minus} from './math.js';// 可以合并成一個(gè)。
    console.log(`默認(rèn)導(dǎo)入:home-->`, home);
    console.log(`單個(gè)導(dǎo)出-導(dǎo)出單個(gè)變量:age-->`, age);console.log(`單個(gè)導(dǎo)出-導(dǎo)出多個(gè)變量:add-->`, add);
    console.log(`單個(gè)導(dǎo)出-導(dǎo)出多個(gè)變量:minus-->`, minus);
    console.log(`單個(gè)導(dǎo)出-導(dǎo)出多個(gè)變量:obj1-->`, obj1);//if(true){
    //    //An import declaration can only be used at the top level of a module.
    //    import home,{age,add,minus} from './math.js';
    //}
    
  • fang/f20230728/f20230728/ES6Module/imdex.html

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>ES6Module</title></head><body>ES6Module<script src="app.js" type="module"></script></body>
    </html>
    

ES6Module詳細(xì)說明

  • fang/f20230728/4.module/3.esmodule/math.js
//單個(gè)導(dǎo)出一個(gè)變量age
export const age = 16;function add(a,b){return a+b;
}
function minus(a,b){return a-b;
}const msg = 'hello';//批量導(dǎo)出add,minus
export {add,minus
}
//一個(gè)模塊中的默認(rèn)導(dǎo)出只能有一個(gè)
export default   '北京'
//A module cannot have multiple default exports.
//export default   '北京'
  • fang/f20230728/4.module/3.esmodule/app.js
import home,{age,add,minus} from './math.js';
console.log(home)
console.log(age)
console.log(add)
console.log(minus)
//if(true){//An import declaration can only be used at the top level of a module.
//    import home,{age,add,minus} from './math.js';
//}
  • fang/f20230728/4.module/3.esmodule/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="app.js" type="module"></script>
</body>
</html>

UMD

  • fang/f20230728/f20230728/UMD/math.js 以UMD規(guī)范來簡(jiǎn)單寫一個(gè)模塊。

    (function (global, factory) {if (typeof define === 'function') {//當(dāng)前處于AMD運(yùn)行環(huán)境define(factory);return}if (typeof module === 'object') {//當(dāng)前處于node中的commonjs模塊化環(huán)境module.exports = factory();//導(dǎo)出factory方法執(zhí)行的結(jié)果 return}// 不是AMD,也不是commonjs,那么就用全局變量的方式。global.math = factory();return})(this, () => {// 這里就是我們要導(dǎo)出去的模塊。return {add(a, b) {return a + b;},minus(a, b) {return a - b;}}
    });// 瀏覽器環(huán)境 self=window=this 沒有g(shù)lobal
    // Node環(huán)境 global=this 沒有self和window
    
  • fang/f20230728/f20230728/UMD/global.html 在瀏覽器以全局變量的方式來導(dǎo)入一個(gè)UMD模塊。

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body>瀏覽器中的global全局環(huán)境<script src="math.js"></script><script>console.log(window.math);</script></body>
    </html>
    
  • fang/f20230728/f20230728/UMD/amd.html 在瀏覽器以AMD的方式的來導(dǎo)入一個(gè)UMD模塊。

    <!DOCTYPE html>
    <html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body>瀏覽器中的AMD環(huán)境<script src="https://unpkg.com/requirejs@2.3.6/require.js"></script><script>//內(nèi)部會(huì)以異步的方式加載math.js文件,并獲取math.js導(dǎo)出的對(duì)象//異步加載完成后會(huì)執(zhí)行回調(diào)函數(shù),把math.js導(dǎo)出的對(duì)象傳進(jìn)去//require方法接收2個(gè)參數(shù),一個(gè)依賴數(shù)組,一個(gè)是回調(diào)函數(shù)//當(dāng)所有依賴都加載成功后,就會(huì)調(diào)用回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)是依賴模塊的輸出require(["math"], (math) => {console.log(math.add(1, 2));});</script></body>
    </html>
    
  • fang/f20230728/f20230728/UMD/commonJs.js 在node中以commonJs方式來導(dǎo)入一個(gè)UMD模塊。

    let math = require('./math');
    console.log(`node中的commonJs環(huán)境:math-->`, math);
    console.log(`node中的commonJs環(huán)境:math-->`, math);
    

UMD詳細(xì)說明

  • fang/f20230728/4.module/4.umd/math.js
(function (global, factory) {if(typeof define === 'function'){//當(dāng)前處于AMD運(yùn)行環(huán)境define(factory);}else if(typeof module === 'object'){//當(dāng)前處于COMMONJS模塊化環(huán)境module.exports = factory();//導(dǎo)出factory方法執(zhí)行的結(jié)果 }else{global.math = factory();}
})(this, () => {return {add(a, b) { return a + b; },minus(a, b) { return a - b; }}
});
// 瀏覽器環(huán)境 self=window=this 沒有g(shù)lobal
// Node環(huán)境 global=this 沒有self和window
  • fang/f20230728/4.module/4.umd/use.js
let math = require('./math');
console.log(math)
  • fang/f20230728/4.module/4.umd/amd.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="https://unpkg.com/requirejs@2.3.6/require.js"></script><script>//內(nèi)部會(huì)以異步的方式加載math.js文件,并獲取math.js導(dǎo)出的對(duì)象//異步加載完成后會(huì)執(zhí)行回調(diào)函數(shù),把math.js導(dǎo)出的對(duì)象傳進(jìn)去//require方法接收2個(gè)參數(shù),一個(gè)依賴數(shù)組,一個(gè)是回調(diào)函數(shù)//當(dāng)所有依賴都加載成功后,就會(huì)調(diào)用回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)是依賴模塊的輸出require(['math'],(math)=>{console.log(math.add(1,2))});</script>
</body>
</html>
  • fang/f20230728/4.module/4.umd/global.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="math.js"></script><script>console.log(window.math)</script>
</body>
</html>
不同環(huán)境下的this
  1. 瀏覽器環(huán)境 self=window=this 沒有g(shù)lobal

    • 瀏覽器控制臺(tái)中

      console.log(this===window)
      console.log(this===self)
      
  2. Node環(huán)境 global=this 沒有self和window

    • fang/f20230728/4.module/4.umd/this.js 主js文件中

      console.log(this===global)
      console.log(this===exports)
      

對(duì)象的函數(shù)寫法

let $ = {ajax: function () {console.log(`ajax-->`, ajax);},
}

這兩種寫法等價(jià)

let $ = {ajax(){console.log(`ajax-->`, ajax);},
}

webpack初步

  • webpack是一個(gè)強(qiáng)大的模塊打包器。
    • 它可以把一個(gè)Web網(wǎng)站所需的資源,像JS、CSS、圖片、圖標(biāo)等等任意的文件都打包在一起。
    • 它的作用是可以從一個(gè)入口文件的出發(fā),識(shí)別出每個(gè)文件之間的依賴關(guān)系,然后將這些資源全部打包成瀏覽器可以識(shí)別和處理的靜態(tài)資源,即打包成一堆js文件或一個(gè)html文件。

初步創(chuàng)建一個(gè)webpack項(xiàng)目

  1. 生成package.json文件。

    npm init -y
    
  2. 安裝webpack所需的依賴。

    npm install webpack webpack-cli --save
    
  3. 創(chuàng)建一個(gè)js文件。

    • fang/f20230728/5.webpack/src/index.js 得到一個(gè)js文件。

      npm install webpack webpack-cli --save
      
  4. 寫一個(gè)簡(jiǎn)單的webpack打包腳本

    {"scripts": {"build": "webpack --mode=development"},
    }
    
  5. 執(zhí)行打包命令。

    npm run build
    

一個(gè)簡(jiǎn)單的webpack示例

  • fang/f20230728/5.webpack/src/index.js 一個(gè)普通的js文件,默認(rèn)的入口文件。

    console.log('main')
    
  • fang/f20230728/5.webpack/package.json 關(guān)于整個(gè)webpack項(xiàng)目的配置信息。

    {"name": "5.webpack","version": "1.0.0","description": "","main": "index.js","scripts": {"build": "webpack --mode=development"},"keywords": [],"author": "","license": "ISC","dependencies": {"webpack": "^5.88.2","webpack-cli": "^5.1.4"}
    }
    
  • fang/f20230728/5.webpack/dist/main.js 執(zhí)行打包命令后出現(xiàn)

/** ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").* This devtool is neither made for production nor for readable output files.* It uses "eval()" calls to create a separate source file in the browser devtools.* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)* or disable the default devtool with "devtool: false".* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).*/
/******/ (() => { // webpackBootstrap
/******/  var __webpack_modules__ = ({/***/ "./src/index.js":
/*!**********************!*\!*** ./src/index.js ***!\**********************/
/***/ (() => {eval("console.log('main')\n\n//# sourceURL=webpack://5.webpack/./src/index.js?");/***/ })/******/  });
/************************************************************************/
/******/  
/******/  // startup
/******/  // Load entry module and return exports
/******/  // This entry module can't be inlined because the eval devtool is used.
/******/  var __webpack_exports__ = {};
/******/  __webpack_modules__["./src/index.js"]();
/******/  
/******/ })()
;

切換npm源

  1. 安裝nrm源切換工具

    npm i nrm -g
    
  2. 測(cè)試不同的源的速度

    nrm test 
    
  3. 切換成淘寶源

    nrm use taobao
    

進(jìn)階參考

http://www.risenshineclean.com/news/1309.html

相關(guān)文章:

  • flash網(wǎng)站建設(shè)技術(shù)成都網(wǎng)絡(luò)優(yōu)化托管公司
  • 各大網(wǎng)站代下單怎么做如何做好互聯(lián)網(wǎng)營(yíng)銷
  • 怎樣維護(hù)公司網(wǎng)站百度搜索資源管理平臺(tái)
  • 做信息網(wǎng)站要辦icp證嗎如何刷seo關(guān)鍵詞排名
  • 虎門仿做網(wǎng)站網(wǎng)上推廣的平臺(tái)有哪些
  • 網(wǎng)站怎么做淘寶客網(wǎng)絡(luò)營(yíng)銷的現(xiàn)狀及問題
  • 如何做學(xué)校網(wǎng)站產(chǎn)品軟文模板
  • 做彩票網(wǎng)站程序違法嗎寧波seo超級(jí)外鏈工具
  • 部門網(wǎng)站建設(shè)個(gè)人總結(jié)網(wǎng)站客服
  • 做婦產(chǎn)科網(wǎng)站優(yōu)化大師電視版
  • 一定要知道的網(wǎng)站培訓(xùn)機(jī)構(gòu)需要什么資質(zhì)
  • 企業(yè)信息系統(tǒng)案例seo網(wǎng)上培訓(xùn)課程
  • 商務(wù)網(wǎng)站的主要內(nèi)容企業(yè)網(wǎng)站排名優(yōu)化方案
  • 一臺(tái)服務(wù)做兩個(gè)網(wǎng)站嗎搜索技巧
  • 濟(jì)南做網(wǎng)站的機(jī)構(gòu)有哪些百度關(guān)鍵詞排名聯(lián)系方式
  • 影視網(wǎng)站怎么做原創(chuàng)百度推廣優(yōu)化排名
  • php購(gòu)物網(wǎng)站搜索欄怎么做怎么樣把廣告做在百度上
  • 教育網(wǎng)站建設(shè)解決方案公司網(wǎng)站建設(shè)服務(wù)機(jī)構(gòu)
  • 安陽網(wǎng)站制作如何增加網(wǎng)站權(quán)重
  • 在線教育網(wǎng)站模板網(wǎng)絡(luò)公司網(wǎng)絡(luò)營(yíng)銷推廣方案
  • 網(wǎng)站版權(quán) 備案icp網(wǎng)絡(luò)公司名字大全
  • 填空秒懂網(wǎng)站女生seo專員很難嗎為什么
  • 長(zhǎng)沙3合1網(wǎng)站建設(shè)寧波seo關(guān)鍵詞排名優(yōu)化
  • 做哪個(gè)網(wǎng)站的推廣最好網(wǎng)絡(luò)營(yíng)銷電子版教材
  • b2b商貿(mào)網(wǎng)站系統(tǒng)域名反查
  • 新媒體運(yùn)營(yíng)師商丘seo
  • 汕頭網(wǎng)址模板建站培訓(xùn)學(xué)校機(jī)構(gòu)有哪些
  • 兼職建設(shè)網(wǎng)站西安自動(dòng)seo
  • 快捷的網(wǎng)站建設(shè)排行榜百度seo關(guān)鍵詞排名查詢
  • 做爰全過程免費(fèi)狐貍網(wǎng)站seo網(wǎng)站優(yōu)化流程