fetch在reactjs中等同於 XMLHttpRequest,它提供了許多與XMLHttpRequest相同的功能,但被設計成更具可擴展性和高效性。javascript
Fetch 的核心在於對 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用於初始化異步請求的 global fetch。得益於 JavaScript 實現的這些抽象好的 HTTP 模塊,其餘接口可以很方便的使用這些功能;除此以外,Fetch 還利用到了請求的異步特性——它是基於 Promise 的。php
請注意,fetch 規範與 jQuery.ajax() 主要有兩種方式的不一樣,牢記:html
當接收到一個表明錯誤的 HTTP 狀態碼時,從 fetch()返回的 Promise 不會被標記爲 reject, 即便該 HTTP 響應的狀態碼是 404 或 500。相反,它會將 Promise 狀態標記爲 resolve (可是會將 resolve 的返回值的 ok 屬性設置爲 false ), 僅當網絡故障時或請求被阻止時,纔會標記爲 reject。java
默認狀況下, fetch 不會從服務端發送或接收任何 cookies, 若是站點依賴於用戶 session,則會致使未經認證的請求(要發送 cookies,必須設置 credentials 選項).node
fetch的使用格式:react
fetch('http://example.com/movies.json') .then(function(response) { return response.json(); }) .then(function(myJson) { console.log(myJson); });
這裏咱們經過網絡獲取一個JSON文件並將其打印到控制檯。最簡單的用法是隻提供一個參數用來指明想fetch()到的資源路徑,而後返回一個包含響應結果的promise(一個 Response 對象)。git
fetch() 接受第二個可選參數,一個能夠控制不一樣配置的 init 對象:github
參考 fetch(),查看全部可選的配置和更多描述ajax
postData('http://example.com/answer', {answer: 42}) .then(data => console.log(data)) // JSON from `response.json()` call .catch(error => console.error(error)) function postData(url, data) { // Default options are marked with * return fetch(url, { body: JSON.stringify(data), // must match 'Content-Type' header cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'same-origin', // include, same-origin, *omit headers: { 'user-agent': 'Mozilla/4.0 MDN Example', 'content-type': 'application/json' }, method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, cors, *same-origin redirect: 'follow', // manual, *follow, error referrer: 'no-referrer', // *client, no-referrer }) .then(response => response.json()) // parses response to JSON }
爲了讓瀏覽器發送包含憑據的請求(即便是跨域源),要將credentials: 'include'添加到傳遞給 fetch()方法的init對象。編程
fetch('https://example.com', { credentials: 'include' })
若是你只想在請求URL與調用腳本位於同一塊兒源處時發送憑據,請添加credentials: 'same-origin'。
// The calling script is on the origin 'https://example.com' fetch('https://example.com', { credentials: 'same-origin' })
要改成確保瀏覽器不在請求中包含憑據,請使用credentials: 'omit'。
fetch('https://example.com', { credentials: 'omit' })
下面的示例片段展現了使用fetch()方法以POST方式發送 JSON編碼的數據:
var url = 'https://example.com/profile'; var data = {username: 'example'}; fetch(url, { method: 'POST', // or 'PUT' body: JSON.stringify(data), // data can be `string` or {object}! headers: new Headers({ 'Content-Type': 'application/json' }) }).then(res => res.json()) .catch(error => console.error('Error:', error)) .then(response => console.log('Success:', response));
在最新瀏覽器API編程中,你可使用一個HTML <input type="file" /> 輸入元素,並結合FormData() 函數和fetch()函數實現上傳文件:
var formData = new FormData(); var fileField = document.querySelector("input[type='file']"); formData.append('username', 'abc123'); formData.append('avatar', fileField.files[0]); fetch('https://example.com/profile/avatar', { method: 'PUT', body: formData }) .then(response => response.json()) .catch(error => console.error('Error:', error)) .then(response => console.log('Success:', response));
若是遇到網絡故障,fetch() (實際上是一個promise對象)將會Reject,帶上一個 TypeError 對象。雖然這個狀況常常是遇到了權限問題或相似問題——好比 404 不是一個網絡故障。想要精確的判斷 fetch() 是否成功,須要包含 promise解析的狀況,此時再判斷 Response.ok 是否是爲 true。相似如下代碼:
fetch('flowers.jpg').then(function(response) { if(response.ok) { return response.blob(); } throw new Error('Network response was not ok.'); }).then(function(myBlob) { var objectURL = URL.createObjectURL(myBlob); myImage.src = objectURL; }).catch(function(error) { console.log('There has been a problem with your fetch operation: ', error.message); });
除了傳給 fetch() 一個資源的地址,你還能夠經過使用 Request() 構造函數來建立一個 request 對象,而後再做爲參數傳給 fetch():
var myHeaders = new Headers(); var myInit = { method: 'GET', headers: myHeaders, mode: 'cors', cache: 'default' }; var myRequest = new Request('flowers.jpg', myInit); fetch(myRequest).then(function(response) { return response.blob(); }).then(function(myBlob) { var objectURL = URL.createObjectURL(myBlob); myImage.src = objectURL; });
Request() 和 fetch() 接受一樣的參數。你甚至能夠傳入一個已存在的 request 對象來創造一個拷貝:
var anotherRequest = new Request(myRequest,myInit);
這個頗有用,由於 request 和 response bodies 只能被使用一次(譯者注:這裏的意思是由於設計成了 stream 的方式,因此它們只能被讀取一次)。建立一個拷貝就能夠再次使用 request/response 了,固然也可使用不一樣的 init 參數。
要在不支持的瀏覽器中使用Fetch,可使用Fetch Polypill(https://github.com/github/fetch)。
上面示例中使用了 fetch API。它是替代 XMLHttpRequest 用來發送網絡請求的很是新的 API。因爲目前大多數瀏覽器原生還不支持它,React開發中建議你使用 cross_fetch 庫(https://github.com/lquixada/cross-fetch):
// 每次使用 `fetch` 前都這樣調用一下
import fetch from 'cross_fetch'
在底層,它在瀏覽器端使用 whatwg-fetch polyfill,在服務器端使用 node-fetch,因此若是當你把應用改爲 同構 時,並不須要改變 API 請求。
注意,fetch polyfill 假設你已經使用了 Promise 的 polyfill。確保你使用 Promise polyfill 的一個最簡單的辦法是在全部應用代碼前啓用 Babel 的 ES6 polyfill:
// 在應用中其它任何代碼執行前調用一次
import 'babel-polyfill'
import fetch from 'cross-fetch' export const REQUEST_POSTS = 'REQUEST_POSTS' function requestPosts(subreddit) { return { type: REQUEST_POSTS, subreddit } } export const RECEIVE_POSTS = 'RECEIVE_POSTS' function receivePosts(subreddit, json) { return { type: RECEIVE_POSTS, subreddit, posts: json.data.children.map(child => child.data), receivedAt: Date.now() } } export const INVALIDATE_SUBREDDIT = ‘INVALIDATE_SUBREDDIT’ export function invalidateSubreddit(subreddit) { return { type: INVALIDATE_SUBREDDIT, subreddit } } // 來看一下咱們寫的第一個 thunk action 建立函數! // 雖然內部操做不一樣,你能夠像其它 action 建立函數 同樣使用它: // store.dispatch(fetchPosts('reactjs')) export function fetchPosts(subreddit) { // Thunk middleware 知道如何處理函數。 // 這裏把 dispatch 方法經過參數的形式傳給函數, // 以此來讓它本身也能 dispatch action。 return function (dispatch) { // 首次 dispatch:更新應用的 state 來通知 // API 請求發起了。 dispatch(requestPosts(subreddit)) // thunk middleware 調用的函數能夠有返回值, // 它會被看成 dispatch 方法的返回值傳遞。 // 這個案例中,咱們返回一個等待處理的 promise。 // 這並非 redux middleware 所必須的,但這對於咱們而言很方便。 return fetch(`http://www.subreddit.com/r/${subreddit}.json`) .then( response => response.json(), // 不要使用 catch,由於會捕獲 // 在 dispatch 和渲染中出現的任何錯誤, // 致使 'Unexpected batch number' 錯誤。 // https://github.com/facebook/react/issues/6895 error => console.log('An error occurred.', error) ) .then(json => // 能夠屢次 dispatch! // 這裏,使用 API 請求結果來更新應用的 state。 dispatch(receivePosts(subreddit, json)) ) } }
let formData = new FormData(); formData.append("key", "123456"); formData.append("secret_key", "123456"); formData.append("telephone", $('#phone').val()); fetch('url',{ method: 'POST', body:formData, dataType: "text", }).then( function(response){ if(response.status!==200){ console.log("存在一個問題,狀態碼爲:"+response.status); return; } //檢查響應文本 response.json().then(function(data){ if(data.code===1){ this.setState({ value : data.data.code }) console.log(data.data.code) } }); } ).catch(function(err){ console.log("Fetch錯誤:"+err); });
react中示例
handleSubmit = (e) => { e.preventDefault(); this.props.form.validateFields((err, values) => { if (!err) { console.log('Received values of form: ', values); console.log('姓名: ', values.userName) console.log('密碼: ', values.password) let url = '/lecheng/public/index.php/index/index/loginAction'; fetch(url, { method: 'POST', headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: 'userName='+values.userName+'&password='+values.password, }).then(response => response.json()).then(function(res) { console.log('返回值[1表明登錄成功,0表明登錄失敗]:') console.log(res) if(res===1){ window.locaion.href="admin.html" }else{ alert('登錄失敗') } console.log(res.status); }); } }); }