一.form表單提交
1.1 簡單的介紹
<!-- form 表單post提交,默認會刷新到 action 頁面 -->
<form action="www.baidu.com" method="POST" name="post提交">
<p>name: <input type="text" name="username"></p>
<p>password: <input type="password" name="password"></p>
<input type="submit" value="提交">
</form>
<!-- form 表單get 提交, 默認刷新action 頁面 -->
<form action="www.baidu.com" method="GET" name="get提交">
<p>name: <input type="text" name="username"></p>
<p>password: <input type="password" name="password"></p>
<input type="submit" value="提交">
</form>
-
form 的提交行爲需要通過type=submit實現
-
form 中的method 屬性不指定時, form 默認的提交方式爲 get請求。
-
表單提交時表單內容會被瀏覽器封裝爲HTTP請求報,裏面包含了所有表單元素的name屬性值和value屬性的值,形式爲name=value。
-
form 表單的提交後會有默認行爲,會跳轉刷新到action 的頁面
-
當一個form 表單內部,所有的input 中只有一個 type=‘text’ 的時候,enter 鍵會有默認的提交行爲(注意前提條件)
-
組織默認行爲可以在
submit
事件時retur false
1.2 編碼方式提交表單數據
<form>
標籤的屬性enctype設置以何種編碼方式提交表單數據。可選的值有三個:
1.這是默認的編碼方式。它只處理表單域裏的value屬性值,採用這種變法方式的表單會將表單域的值處理成URL方式。
application/x-www-form-urlencoded:
2.這種編碼方式會以二進制流的方式來處理表單數據,這中編碼方式會把文件域指定的文件內容也封裝到請求參數裏。
multipart/form-data:
不用後臺接受這樣的數據,需要注意,接受的可能是:
------WebKitFormBoundaryQqpAxgR2Pgik6uyY
Content-Disposition: form-data; name="f"; filename="hello.txt"
Content-Type: application/octet-stream
這時需要處理,例如node可以採用formidabled
或者multiparty
插件處理
3.這種方式當表單的action屬性值爲mailto:URL的形式時比較方便,這種方式主要適用於直接通過表單發送郵件。
text/plain:
1.3 form表單爲何沒有跨域限制
跨域問題只是瀏覽器強加給js的規則。瀏覽器強制不允許js訪問別的域,但是瀏覽器卻沒有限制它自己。比如說img標籤可以加載任何域的圖片,script可以加載任何域的js。
form 提交是瀏覽器行爲,提交到另一個域名之後,原頁面的腳本無法獲取新頁面中的內容。所以瀏覽器認爲這是安全的。
而 AJAX 是可以讀取響應內容的,因此瀏覽器不能允許你這樣做。如果你細心的話你會發現,其實請求已經發送出去了,你只是拿不到響應而已。所以瀏覽器這個策略的本質是,一個域名的 JS ,在未經允許的情況下,不得讀取另一個域名的內容。但瀏覽器並不阻止你向另一個域名發送請求。
二.ajax
JavaScript執行異步網絡請求。
如果仔細觀察一個Form的提交,你就會發現,一旦用戶點擊“Submit”按鈕,表單開始提交,瀏覽器就會刷新頁面,然後在新頁面裏告訴你操作是成功了還是失敗了。如果不幸由於網絡太慢或者其他原因,就會得到一個404頁面。
這就是Web的運作原理:一次HTTP請求對應一個頁面。
如果要讓用戶留在當前頁面中,同時發出新的HTTP請求,就必須用JavaScript發送這個新請求,接收到數據後,再用JavaScript更新頁面,這樣一來,用戶就感覺自己仍然停留在當前頁面,但是數據卻可以不斷地更新。
在現代瀏覽器上寫AJAX主要依靠XMLHttpRequest對象:
var xhr=new XMLHttpRequest();
xhr.open("GET","ajax_info.txt",true);
xhr.send();
xhr.onreadystatechange=function (){
if(xhr.readyState==4){
if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
alert('成功');
let json=JSON.parse(xhr.responseText);
console.log(json);
}else{
alert('失敗');
}
}
};
屬性 | 描述 |
---|---|
open(method,url,async) | 規定請求的類型、URL 以及是否異步處理請求。 method:請求的類型;GET 或 POSTurl:文件在服務器上的位置async:true(異步)或 false(同步) |
send(string) | 將請求發送到服務器。string:僅用於 POST 請求 |
onreadystatechange | 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。 |
readyState | 存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。0: 請求未初始化1: 服務器連接已建立2: 請求已接收3: 請求處理中4: 請求已完成,且響應已就緒 |
responseText | 獲得字符串形式的響應數據 |
status | 200-300表示成功,304表示使用緩存 |
三. fatch
MDN介紹
如果遇到不支持fech的可以使用第三方的ployfill來實現只會fetch:whatwg-fetch
有一篇文章寫的很好,我這裏就不廢話了https://segmentfault.com/a/1190000011433064
這裏只幾個舉例子
可以使用async await
獲取文本
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.請求
let res=await fetch('data/1.txt');
//2.解析
let str=await res.text();
alert(str);
};
獲取json
window.onload=function (){
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.請求
let res=await fetch('data/1.json');
//2.解析
let json=await res.json();
console.log(json);
};
};
獲取圖片
window.onload=function (){
let oImg=document.getElementById('img1');
let oBtn=document.getElementById('btn1');
oBtn.onclick=async function (){
//1.請求
let res=await fetch('data/1.png');
//2.解析
let data=await res.blob();
let url=URL.createObjectURL(data);
oImg.src=url;
};
};
.四fomdata
ajax2
添加了一個新的接口FormData
. 利用FormData
對象,我們可以通過JavaScript用一些鍵值對來模擬一系列表單控件,我們還可以使用XMLHttpRequest
的send()
方法來異步的提交這個"表單".比起普通的ajax,使用FormData
的最大優點就是我們可以異步上傳一個二進制文件.
直接來看例子:
基本使用:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form id="form1" action="http://localhost:8080/" method="post">
用戶:<input type="text" name="user" /><br>
密碼:<input type="password" name="pass" /><br>
文件:<input type="file" name="f1" /><br>
<input type="submit" value="提交">
</form>
</body>
<script>
let oForm=document.querySelector('#form1');
oForm.onsubmit=function (){
// new一個FormData實例
let formdata=new FormData(oForm);
// 這是ajax
let xhr=new XMLHttpRequest();
xhr.open(oForm.method, oForm.action, true);
xhr.send(formdata);
xhr.onreadystatechange=function (){
if(xhr.readyState==4){
if(xhr.status==200){
alert('成功');
}else{
alert('失敗');
}
}
};
return false;
};
</script>
</html>
利用jq
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form id="form1" action="http://localhost:8080/" method="post">
用戶:<input type="text" name="user" /><br>
密碼:<input type="password" name="pass" /><br>
文件:<input type="file" name="f1" /><br>
<input type="submit" value="提交">
</form>
</body>
<script src="jquery.js" charset="utf-8"></script>
<script>
$('#form1').on('submit', function (){
let formdata=new FormData(this);
$.ajax({
url: this.action,
type: this.method,
data: formdata,
//
processData: false,
// FormData時jq會自動改變類型,我們不允許
contentType: false
}).then(res=>{
alert('成功');
}, res=>{
alert('失敗');
});
return false;
});
</script>
</html>
不實用form表單
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
用戶:<input type="text" id="user" /><br>
密碼:<input type="password" id="pass" /><br>
文件:<input type="file" id="f1" /><br>
<input id="btn1" type="button" value="提交">
</div>
</body>
<script>
let oBtn=document.querySelector('#btn1');
oBtn.onclick=function (){
let formdata=new FormData();
formdata.append('username', document.querySelector('#user').value);
formdata.append('password', document.querySelector('#pass').value);
formdata.append('f1', document.querySelector('#f1').files[0]);
//
let xhr=new XMLHttpRequest();
xhr.open('post', 'http://localhost:8080/', true);
xhr.send(formdata);
xhr.onreadystatechange=function (){
if(xhr.readyState==4){
if(xhr.status==200){
alert('成功');
}else{
alert('失敗');
}
}
};
};
</script>
</html>
使用node接收數據
multiparty需要install
const http=require('http');
const multiparty=require('multiparty');
http.createServer((req, res)=>{
let form=new multiparty.Form({uploadDir: './upload/'});
form.parse(req);
form.on('field', (name, value)=>{
console.log('field:', name, value);
});
form.on('file', (name, file)=>{
console.log('file:', name, file);
});
form.on('close', ()=>{
console.log('完事');
});
}).listen(8080);
四。在服務端設置跨域
我們以node作爲後端,直接來設置
const http=require('http');
// 我們允許訪問的地址
let allowOrigin={
'http://localhost': true,
'http://aaa.com': true,
'https://aaa.com': true,
}
http.createServer((req, res)=>{
let {origin}=req.headers;
if(allowOrigin[origin]){
// 設置爲*表示允許任何地址訪問
res.setHeader('access-control-allow-origin', '*');
}
res.write('{"a": 12, "b": "Blue"}');
res.end();
}).listen(8080);