Hi老师,我们这个课程封装的post是不是没办法用在我们自己写的后端?

来源:4-6 基于HiNet实现登录功能

慕尼黑0536602

2022-02-10

hi老师,
(我使用了咱们这堂课的后端接口,没有任何问题)
就是当我尝试用咱们这门课的post封装+我自己写的登录后端(node.js写的),发现email(相当于这门课的userName)和password都接收不到。
下面是我用Postman做的测试,返回的数据:

{
    "code": 0,
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyMDI2N2JmMjZmNjUyNzFkYjFkZTBjMiIsImlhdCI6MTY0NDQ5NjQxNX0.zg5USpeIlbqCATe4kZ5FelD26Qs6gbt1VmhsJxtfRiY",
    "data": {
        "_id": "620267bf26f65271db1de0c2",
        "email": "coco@gmail.com",
        "password": "123",
        "active": true,
        "__v": 0
    },
    "msg": "success"
}

然后使用的是咱们上次课教的post:

/**
 * 
 * @param api 对应Constants里的api,即各个接口
 * @returns 第一个参数作为body参数,第二个参数作为URL path 或者查询参数
 */
 export function postGR(api:string){
    return (params:{}) =>{
        return async (queryParams?: {} | string) => {
            const { url } = ConstantGR;
            var data, cType;
         if(params instanceof FormData) {
             data = params;
             cType ='multipart/form-data'
         }else{
            data = JSON.stringify(params);
            cType = 'application/json';
         }
            return handleData(fetch(buildParams(url+api,queryParams),
            {
                method:'POST',
                body:data,
                headers:{
                    'content-type':cType,
                   
                }
            }
            ))
        }
    }
}

/**
 * 处理接口返回数据
 * @param doAction 
 */
function handleData(doAction:Promise<any>){
    return new Promise((resolve,reject)=>{
        doAction.then((res)=>{
            //解析Content-Type 防止非json数据进行Json转换
            const type= res.headers.get('Content-Type');
          if((type||'').indexOf('json') !== -1){
              return res.json();
          }
          return res.text();
        }).then((result)=>{
            console.log(JSON.stringify(result));
            if(typeof result ==="string"){
                throw new Error(result);
            }
           const{code,msg,data:{list = undefined}={}} = result;
           if(code === 401){
               //跳转到登录页
           }
           resolve(list||result);
        }).catch((error)=>{
            reject(error);
        })
    });
}

/**
 * 构建URL参数
 * @param url 
 * @param params 
 * @returns 
 */
 function buildParams(url:string,params?:{}|string):string{
    let newUrl = new URL(url),finalUrl;
    if(typeof params === 'object'){
        for(const [key,value] of Object.entries(params)){
            newUrl.searchParams.append(key,value as string);
        }
        finalUrl = newUrl.toString();
    }else if(typeof params === 'string'){
        //适配path
        finalUrl = url.endsWith('/')?url+params:+"/"+params;
    }else{
        finalUrl = newUrl.toString();
    }
    console.log("我们最终获得的finalUrl:",finalUrl);
    return finalUrl;
 }

接着重新再弄了一个LoinDaoGR:

import ConstantGR from "./ConstantGR";
import { postGR } from "./NetGR";

export default class LoginDaoGR{
    public static instance:LoginDaoGR;
    private constructor(){};
    public static getInstance() :LoginDaoGR {
        if(!LoginDaoGR.instance){
            LoginDaoGR.instance = new LoginDaoGR();
        }
        return LoginDaoGR.instance;
    }

    login(email:string,passsword:string):Promise<any>{
        return new Promise((resolve,reject)=>{
            const {login:{api}} = ConstantGR
            const formData = new FormData();
            formData.append('email',email);
            formData.append('password',passsword);
            postGR(api)(formData)().then((res:any)=>{
                const {code,data,token,msg}=res ;
                if(code===0){
                    resolve(data||resolve);
                }else{
                    reject(res);
                }
            }
        
            ).catch(e=>{
                console.log(e);
                reject({code:-1,msg:'出错啦'});
            }
                );
        });
    }
     

}

接下来就是使用了,这里我用咱们课的设计的登录界面做测试,发现收到的回复是400 ,查看了 email 和 password收到的都是undefine . 我在postman 中传入:email 和 password没有问题:

import { Pressable, StyleSheet, Text, View,TouchableOpacity } from 'react-native'
import React,{useState} from 'react'
import LoginComponent from './../common/LoginComponent';
import LoginButton from '../common/LoginButton';
import LoginTips from '../common/LoginTips';
import LoginDaoGR from '../expand/dao/LoginDaoGR';

const LoginPage = () => {
    //const [userName,setUserName] = useState('');
    const [email,setEmail] = useState('');
    const [password,setPassword] = useState('');
    const [msg,setMsg] = useState('ddd');
    const [helperUrl,setHelperUrl]=useState("http://www.google.com");
    const login =()=>{
      if(!email||!password){
        setMsg("用户名和密码不能为空");
        return;
      }
      setHelperUrl('');
      setMsg('');
    
      LoginDaoGR.getInstance()
                .login(email,password)
                .then((res)=>{
                  setMsg("登录成功");
                })
                .catch(e =>{
                  const {code,token,data:{helpUrl =''}={},msg} = e;
                  setMsg(msg);
                  setHelperUrl(helpUrl);
                });
      
     }
  return (
    <View style={{flex:1,alignItems:'center'}}>
        <View style={{flexDirection:'row',justifyContent:"space-around",padding:30,width:'100%'}}>
        <View/>
        <Text style={{fontSize:20,color:'black'}}>登录</Text>

        <TouchableOpacity>
            <Text style={{fontSize:20,color:'blue'}}>注册</Text>
        </TouchableOpacity>
        </View>
      <LoginComponent label={"用户名"} placeHolder="用户名" textColor={'black'} secure={false} onChangeText ={(text:string)=>setEmail(text)}/>
      <LoginComponent label={"密码"} placeHolder="密码" textColor={'black'} secure={true} onChangeText ={(text:string)=>setPassword(text)} />
      <LoginButton title={"登录"} onPress={login}/>
      <LoginTips msg = {msg} helpUrl={helperUrl}/>
    </View>
  )
}

export default LoginPage

const styles = StyleSheet.create({})

代码有点儿多,辛苦老师帮我看一下哈!谢谢您!

写回答

2回答

CrazyCodeBoy

2022-02-11

这是因为你的服务端接口接受的是application/json类型的请求导致的

0
1
慕尼黑0536602
hi老师,很感谢您的提醒,我刚刚强制,把headers里content-type ,修改成: Content-Type:“multipart/form-data” ,但是接收到的email 还有 password 还是undefine ..但是我看了咱们上节课的代码,应该能够有自动判断的呀,就是当params是FormData的时候,转为 'multipart/form-data' ;如果params是JSON.stringify(params) ,就改成'application/json' ; 所以我还是不清楚要修改哪里?T^T .
2022-02-11
共1条回复

慕尼黑0536602

提问者

2022-02-11

hi老师,经过不断地尝试,我使用了下面的代码,结果就可以用我自己写的后端了:

 fetch("http://192.168.1.124:3000/api/v1/users/auth/login",{

        method:'POST',

        headers:{

          'Content-Type':'application/json'

        },

        body : JSON.stringify({

          "email":email,

          "password":password

        })


      })

      .then(res =>res.json())

      .then(data =>{

        console.log(data);

        setMsg("登录成功");

      }).catch(e=>{

        console.log(e);

      })


所以我也不知道是哪里出了问题。。 ==|||


0
0

RN入门到进阶,打造高质量上线App

解锁React Native开发应用新姿势,React Native新版本热门技术

3144 学习 · 3241 问题

查看课程