mcya / JavaScriptExperience

👮 JavaScript Experience for web(JavaScript归类:简单入门+数组+经典循环+字符串+函数+Date日期+简单对象+BOM+DOM) +[ Issues(js实用技巧)]
29 stars 8 forks source link

关于HTTP的一些事情 #71

Open mcya opened 5 years ago

mcya commented 5 years ago

汇总一下关于http 出现的一些跨域之类的问题探索

mcya commented 5 years ago

xFetch.js

// import React from 'React'
import 'isomorphic-fetch'
import 'fetch-detector';
import 'fetch-ie8';
import { parseParam, cleanLoginInfo } from './index'
import MsgBox from 'MsgBox'
import { isRepeatClick } from 'util'

const fetch = window.fetch;
const errorMessages = (res) => `${res.status} ${res.statusText}`;

function handleHttpError(res) {
// console.log('----------handleHttpError:', res);
  if (res.status === 401) {
    cleanLoginInfo();
    location.reload(false);
  } else if (res.status === 404) {
      return Promise.reject(errorMessages(res));
  }

  return res;
}

function handle401(res) {
  if (res.jsonResult.code === -1) {
    cleanLoginInfo();
    location.reload(false);
  }

  return res;
}

function jsonParse(res) {
  return res.json().then(jsonResult => ({ ...res, jsonResult }));
}

function errorMessageParse(res) {
  const { success, message } = res.jsonResult;
  if (!success) {
    return Promise.reject(message);
  }
  return res;
}

/*function checkNoLogin(res) {
  const { success, message, code } = res.jsonResult;
  if (!success && message.indexOf('未登录')) {
    MsgBox.warning({
      title: '快速登录',
      content: (
        <div>
          <span>用户未登录或登录超时</span>
        </div>
      )
    })
  }
  return res;
}*/

function xFetch(url, options) {
  // if (isRepeatClick(url)) return;
  const opts = { ...options, credentials: 'include' };
  opts.headers = {
    ...opts.headers
  };

  if(__CONTEXT__){
    url = __CONTEXT__ + url;
  }

  return fetch(url, opts)
    .then(jsonParse)
    .then(handleHttpError)
    .then(handle401)
    // .then(checkNoLogin)
    .then(errorMessageParse);
}

export function Post(url, params = {}) {
  params._ = new Date().getTime();//add cache
  const query = parseParam(params);
  return xFetch(url, {
    method: 'POST',
    headers: {
      Accept: 'text/javascript, text/html, application/xml, text/xml, */*',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: query
   });
}
export function Post2(url, params = {}) {
  // params._ = new Date().getTime();//add cache
  const query = params;
  return xFetch(url, {
    method: 'POST',
    headers: {
      Accept: 'text/javascript, text/html, application/xml, text/xml, */*',
      'Content-Type': 'application/json'
    },
    body: query
   });
}

export function Get(url, params = {}) {
  params._ = new Date().getTime();//add cache
  const query = parseParam(params);
  return xFetch(`${url}?${query}`, { method: 'GET' });
}

export function PostJsonBody(url, params = '') {
  //const query = parseParam(params);
  return xFetch(url, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json;charset=UTF-8'
    },
    body: params
   });
}

export default xFetch;
mcya commented 5 years ago

关于 xFetch.js 的使用

1. api. js 常规操作

import { Post } from 'xFetch';

export function proceUpdate(params) {
    return Post('/proce/update.do', params);
}

2. jsx/js 中引入使用

import { PostJsonBody, Post2 } from 'xFetch';

 testAction() {
   const bpmUrl = getBPMHost();
   var bpmUrlActionApi = bpmUrl+"/YZSoft/WebService/YZService.ashx?Method=PublicExt&UserAccount="+this.props.userInfo.user.usercode;
   var paramss = { TaskID: "22292" };
   var testuuu = "/mingyuandata/getImportResult.do"

   let api = PostJsonBody(bpmUrlActionApi, JSON.stringify(paramss) );
   api.then(({ jsonResult = { data: [] } }) => {
     console.log("jsonResult~pbm", jsonResult.data);
   })

 }
let api = PostJsonBody(bpmUrlActionApi, JSON.stringify(paramss) );
   api.then(({ jsonResult = { data: [] } }) => {
     console.log("jsonResult~pbm", jsonResult.data);
   })

3. 关于PostJsonBodyPost

Post 常规传参的post请求

PostJsonBody 用于传递json对象的post请求
PostJsonBody 传递格式如下图:

image

4. 使用 PostJsonBody 请求出现 options 状态(一般是跨域或者夸后台包出现)的解决

如果想要用ContentType:application/json发送跨域请求,服务器端还必须设置一个名为
Access-Control-Allow-Headers 的Header,将它的值设置为 Content-Type,表明服务器能够接收
到前端发送的请求中的ContentType属性并使用它的值。否则第二次请求也是发不出去的,浏览器console会
报错,并提示你服务器没有设置Access-Control-Allow-Headers。