微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React中的fetch请求相关

fetch在reactjs中等同于 XMLHttpRequest,它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。

Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch。得益于 JavaScript 实现的这些抽象好的 HTTP 模块,其他接口能够很方便的使用这些功能;除此之外,Fetch 还利用到了请求的异步特性——它是基于 Promise 的。

请注意,fetch 规范与 jQuery.ajax() 主要有两种方式的不同,牢记:

  • 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ), 仅当网络故障时或请求被阻止时,才会标记为 reject。

  • 认情况下,fetch 不会从服务端发送或接收任何 cookies,如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项).

fetch的使用格式:

基本的请求示例:

fetch(‘http://example.com/movies.json‘)
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

这里我们通过网络获取一个JSON文件并将其打印到控制台。最简单的用法是只提供一个参数用来指明想fetch()到的资源路径,然后返回一个包含响应结果的promise(一个 Response 对象)。

第二个可选参数

fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象:

参考 fetch(),查看所有可选的配置和更多描述

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‘  
})

上传 JSON 数据

下面的示例片断展示了使用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:‘,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 参数。

React开发中使用fetch

要在不支持的浏览器中使用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‘

 

 

一个相对完整的使用fetch的例子

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);
                });
            }
        });
    }

部分转载自51cto,csdn

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐