跟着视频里敲的代码实现效果有些不太一样

跟着视频里敲的代码实现效果有些不太一样

在index.html中,视频里老师调用success方法是这么写的:

https://img1.sycdn.imooc.com//climg/62e7943809b3b7da06030720.jpg


我在vs code上这么写却没能获取到响应:

https://img1.sycdn.imooc.com//climg/62e794ba0993f74607340346.jpg

https://img1.sycdn.imooc.com//climg/62e795470986d80708930338.jpg


然后我把代码做了如下修改就能得到结果了:

https://img1.sycdn.imooc.com//climg/62e795a309a3d20905650441.jpg

https://img1.sycdn.imooc.com//climg/62e795bc098a620d08830568.jpg

请问老师这是为什么呢?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕慕子 2022-08-01 17:12:48

同学你好,猜测可能是封装ajax方法中的代码与讲师书写的不一致导致的,讲师在封装时,传入success中的参数为xhr.response和xhr两个参数,其中的xhr.response表示返回的数据,xhr是备选项,防止以后需要使用。

https://img1.sycdn.imooc.com//climg/62e7990b0965119509020627.jpg

祝学习愉快~

  • 提问者 困惑小张 #1

    这块写的跟讲师视频里讲的是一致的呀,代码麻烦老师帮忙看看

    ajax.js:

    //常量
    import { HTTP_GET, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_JSON } from "./constants.js";
    
    //工具函数
    import { serialize, addURLData, serializeJSON } from "./utils.js";
    
    //默认参数
    import DEFAULTS from "./default.js";
    
    //Ajax类
    class Ajax {
        constructor(url, options) {
            this.url = url;
            this.options = Object.assign({}, DEFAULTS, options);
    
            //初始化
            this.init();
        }
    
        //初始化
        init() {
            const xhr = new XMLHttpRequest();
            this.xhr = xhr;
    
            //绑定响应事件处理程序
            this.bindEvents();
    
            xhr.open(this.options.method, this.url + this.addParam(), true);
    
            //设置responseType
            this.setResponseType();
    
            //设置跨域是否携带Cookie
            this.setCookie();
    
            //设置超时
            this.setTimeout();
    
            //发送请求
            this.sendData();
        }
    
        //绑定响应事件处理程序
        bindEvents() {
            const xhr = this.xhr;
    
            const { success, httpCodeError, error, abort, timeout } = this.options;
    
            //load
            xhr.addEventListener('load', () => {
                if (this.ok()) {
                    success(xhr.response, xhr);
                } else {
                    httpCodeError(xhr.status, xhr);
                }
            }, false);
    
            //error
            xhr.addEventListener('error', () => {
                error(xhr);
            }, false);
    
            //abort
            xhr.addEventListener('abort', () => {
                abort(xhr);
            }, false);
    
            //timeout
            xhr.addEventListener('timeout', () => {
                timeout(xhr);
            }, false);
        }
    
        //检测响应的HTTP状态码是否正常
        ok() {
            const xhr = this.xhr;
            return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304
        }
    
        //在地址上添加数据
        addParam() {
            const { params } = this.options;
    
            if (!params) return '';
    
            return addURLData(this.url, serialize(params));
        }
    
        //设置responseType
        setResponseType() {
            this.xhr.responseType = this.options.responseType;
        }
    
        //设置跨域是否携带Cookie
        setCookie() {
            if (this.options.withCredentials) {
                this.xhr.withCredentials = true;
            }
        }
    
        //设置超时
        setTimeout() {
            const { timeoutTime } = this.options;
    
            if (timeoutTime > 0) {
                this.xhr.timeout = timeoutTime;
            }
        }
    
        //发送请求
        sendData() {
            const xhr = this.xhr;
    
            if (!this.isSendData()) {
                return xhr.send(null);
            }
    
            let resultData = null;
            const {data}=this.options;
    
            //发送FormData数据
            if (this.isFormData()) {
                resultData = data;
            } else if (this.isFormURLEncodedData()) {
                //发送application/x-www-form-urlencoded数据
                this.setContentType(CONTENT_TYPE_FORM_URLENCODED);
                resultData = serialize(data);
            } else if (this.isJSONData()) {
                发送application / json格式的数据
                this.setContentType(CONTENT_TYPE_JSON);
                resultData = serializeJSON(data);
            } else {
                //发送其他格式的数据
                this.setContentType();
                resultData = data;
            }
    
            xhr.send(resultData);
        }
    
        //是否需要使用send发送数据
        isSendData() {
            const { data, method } = this.options;
    
            if (!data) return false;
    
            if (method.toLowerCase() === HTTP_GET.toLowerCase()) return false;
    
            return true;
        }
    
        //是否是FormData数据
        isFormData() {
            return this.options.data instanceof FormData;
        }
    
        //是否是application/x-www-form-urlencoded数据
        isFormURLEncodedData() {
            return this.options.contentType.toLowerCase().includes(CONTENT_TYPE_FORM_URLENCODED);
        }
    
        //是否是json数据
        isJSONData() {
            return this.options.contentType.toLowerCase().includes(CONTENT_TYPE_JSON);
        }
    
        //设置Content-Type
        setContentType(contentType=this.options.contentType){
            if(!contentType) return;
    
            this.xhr.setRequestHeader('Content-Type',contentType);
        }
    
        //获取XHR对象
        getXHR(){
            return this.xhr;
        }
    }
    
    export default Ajax;


    constants.js:

    //常量模块
    export const HTTP_GET='GET';
    export const CONTENT_TYPE_FORM_URLENCODED='application/x-www-form-urlencoded';
    export const CONTENT_TYPE_JSON='application/json';
    
    export const ERROR_HTTP_CODE=1;
    export const ERROR_HTTP_CODE_TEXT='HTTP状态码异常:';
    export const ERROR_REQUEST=2;
    export const ERROR_REQUEST_TEXT='请求被阻止';
    export const ERROR_TIMEOUT=3;
    export const ERROR_TIMEOUT_TEXT='请求超时';
    export const ERROR_ABORT=4;
    export const ERROR_ABORT_TEXT='请求终止';


    utils.js:

    //工具函数
    
    //数据序列化成urlencoded格式的字符串
    const serialize=param=>{
        const results=[];
    
        for(const [key,value] of Object.entries(param)){
            results.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
        }
    
        return results.join('&');
    };
    
    const serializeJSON=param=>{
        return JSON.stringify(param);
    }
    
    //给URL添加参数
    //www.imooc.com?words=js&name=alex
    const addURLData=(url,data)=>{
        if(!data) return '';
    
        const mark=url.includes('?')?'&':'?';
    
        return `${mark}${data}`;
    }
    
    export {serialize,addURLData,serializeJSON};


    default.js:

    //常量
    import { HTTP_GET ,CONTENT_TYPE_FORM_URLENCODED} from "./constants.js";
    
    //默认参数
    const DEFAULTS={
        method:HTTP_GET,
        //请求头携带的数据
        params:null,
        // params:{
        //     username:'alex',
        //     age:18
        // }  POST请求携带数据的格式
    
        //请求体携带的数据
        data:null,
        // data:{
        //     username:'alex',
        //     age:18
        // }  POST请求携带数据的格式
        // 或者 data:FormData 数据
    
        contentType:CONTENT_TYPE_FORM_URLENCODED,
        responseType:'',
        timeoutTime:0,
        withCredentials:false,
    
        //方法
        success(){},
        httpCodeError(){},
        error(){},
        abort(){},
        timeout(){}
    }
    
    export default DEFAULTS;


    index.js:

    import Ajax from "./ajax.js";
    
    //常量
    import{
        ERROR_HTTP_CODE,
        ERROR_HTTP_CODE_TEXT,
        ERROR_REQUEST,
        ERROR_REQUEST_TEXT,
        ERROR_TIMEOUT,
        ERROR_TIMEOUT_TEXT,
        ERROR_ABORT,
        ERROR_ABORT_TEXT
    } from './constants.js';
    const ajax =(url,options) =>{
        return new Ajax(url,options).getXHR();
    };
    
    const get=(url,options)=>{
        //将options展开,后面的method:'GET'会覆盖掉options里的method
        return ajax(url,{...options,method:'GET'});
    };
    
    const getJSON=(url,options)=>{
        return ajax(url,{...options,method:'GET',responseType:'json'});
    };
    
    const post=(url,options)=>{
        return ajax(url,{...options,method:'POST'});
    };
    
    export {ajax,get,getJSON,post};


    index.html:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <script type="module">
            import {ajax,get,getJSON,post} from './index.js';
            const url='https://www.imooc.com/api/http/search/suggest?words=js';
    
            const xhr=ajax(url,{
                method:'POST',
                params:{username:'alex'},
                data:{
                    age:18
                },
                ResponseType:'json',
    
                success(response){
                    console.log(xhr.response);
                },
    
                httpCodeError(err){
                    console.log('http code error',err);
                },
    
                error(xhr){
                    console.log('error',xhr);
                },
                abort(xhr){
                    console.log('abort',xhr);
                },
                timeout(xhr){
                    console.log('timeout',xhr);
                },
            });
    
        </script>
    </body>
    </html>



    2022-08-01 17:53:45
  • 好帮手慕慕子 回复 提问者 困惑小张 #2

    同学你好,测试同学粘贴的代码,直接输出response也是可以得到结果的,如下:

    https://img1.sycdn.imooc.com//climg/62e7a6280900a63217310657.jpg

    直接使用xhr.response方式可以理解是另一种获取数据的方式。另外,同学传入的参数responseType属性名和使用时的首字母大小写不一致,建议修改:

    https://img1.sycdn.imooc.com//climg/62e7a7e70980c59919200694.jpg

    祝学习愉快~

    2022-08-01 18:16:22
  • 提问者 困惑小张 回复 好帮手慕慕子 #3

    老师,直接输出response是可以得到结果,但是我这边浏览器里的network里却没有xhr的请求,但是xhr.response却可以,不理解这是为什么

    2022-08-02 12:14:46
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师