POST 请求适用于 Postman,但不适用于 axios 或 .fetch()

Posted

技术标签:

【中文标题】POST 请求适用于 Postman,但不适用于 axios 或 .fetch()【英文标题】:POST request works with Postman, but not with axios or .fetch() 【发布时间】:2018-06-22 18:47:28 【问题描述】:

我有一个问题,我已经处理了几天,但找不到解决方案。我用 Lumen 创建了一个 API,用 ReactJS 创建了一个前端。这一切都适用于 GET 请求,但是当我发送 POST 请求时它会失败。由于某些奇怪的原因,当我使用 Postman 发送请求时,这些请求有效。 现在有一些代码!

首先是发送请求的 JS-Script:

import moment from 'moment';
import React, Component from 'react';
import  Modal, Form, Button, Input, DatePicker, Select, message  from 'antd';

const RangePicker = DatePicker;
const FormItem = Form.Item;
const Option = Select.Option;

const api_url = 'api/v1/';

class NewEventForm extends React.Component 
    constructor(props) 
        super(props);

        this.state = 
            confirmLoading: false,
            categories: []
        ;

        this.onCreate = this.onCreate.bind(this);
        this.onCancel = this.onCancel.bind(this);
    

    componentDidMount() 
        fetch(api_url + 'category')
        .then(results => 
            return results.json();
        ).then(data => 
            let categories = data.map((cat) => 
                return (
                    <Option key=cat.id value=cat.id>cat.name</Option>
                    );
            );
            this.setState(categories: categories);
        );
    
    
    updateStates() 
        this.props.updateState();
        this.setState(confirmLoading: false);
    

    onCreate() 
        this.props.form.validateFields((err, values) => 
            this.setState(
                confirmLoading: true
            );

            if (err) 
                this.setState(
                    confirmLoading: false
                );
                return;
            
            
            let event = 
                title: values.title,
                description: values.description,
                start_time: values.date[0],
                end_time: values.date[1],
                category_id: values.category
            ;
            
            fetch(api_url + 'event', 
                method: 'POST',
                /* headers are important*/
                headers: 
                    "content-type":"application/json",
                    "cache-control":"no-cache",
                    "accept":"*/*",
                ,
                body: JSON.stringify(event)
            ).then(response => 
                if(response.ok) 
                    return response.json();
                
                throw new Error("Antwort der API war nicht 'Ok'!");
            ).then(data =>
                this.updateStates();
                
                message.success('Das Ereignis wurde erfolgreich eingetragen!');              
            ).catch(error => 
                //console.log(error);
                this.updateStates();
                
                message.error('Das Ereignis wurde nicht erstellt. Bitte versuche es später nochmal!'); 
            );
        );
    
    onCancel(e) 
        e.preventDefault();

        this.updateStates();
    

    render() 
        const getFieldDecorator, getFieldError = this.props.form;

        return(
                <Modal title="Neue Veranstaltung hinzufügen" okText="Eintragen" confirmLoading=this.state.confirmLoading visible=this.props.visible onOk=this.onCreate onCancel=this.onCancel>
                    <Form layout="vertical">
                        <FormItem label="Titel">
                            getFieldDecorator('title', 
                                rules: [required: true, message: 'Bitte einen Titel angeben!' ],
                            )(
                            <Input />
                            )
                        </FormItem>
                        <FormItem label="Beschreibung">
                            getFieldDecorator('description')(<Input type="textarea" />)
                        </FormItem>
                        <FormItem label="Kategorie">
                            getFieldDecorator('category', 
                                rules: [required: true, message: 'Bitte einen Kategorie auswählen!' ],
                            )(
                            <Select placeholder="Kategorie auswählen...">
                                this.state.categories
                            </Select>
                            )
                        </FormItem>
                        <FormItem label="Zeitraum" className="collection-create-formlast-form-item">
                            getFieldDecorator('date', 
                                rules: [required: true, message: 'Bitte einen Zeitraum auswählen!' ],
                            )(
                            <RangePicker
                                showTime=
                                    hideDisabledOptions: true,
                                    defaultValue: [moment('00:00', 'HH:mm'), moment('00:00', 'HH:mm')],
                                    format: 'HH:mm'
                                
                                format="DD.MM.YYYY HH:mm"
                                />
                            )
                        </FormItem>
                    </Form>
                </Modal>
                );
    


export const NewEventModal = Form.create()(NewEventForm);

我的数据库有三个模型。事件、类别和用户: Category.idEvent.category_id||Event.updated_byUser.id

现在是 EventController:

<?php

namespace App\Http\Controllers;

use App\Event;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;


class EventController extends Controller


    public function index()
        $Events = Event::all();

        return response()->json($Events);  
    

    public function getEvent($id)  
        $Event = Event::with(['category', 'user'])->find($id);

        return response()->json($Event);
    

    public function createEvent(Request $request)
        $User  = \App\User::find(1);
        $Category = \App\Category::find(1);

        $Event = new Event;
        $Event->fill($request->all());
        $Event->user()->associate($User);
        $Event->category()->associate($Category);

        $obj = '';
        foreach ($request->all() as $key => $value) 
            $obj .= '[' . $key . '] => "' . $value . '"; ';
        

        \Log::warning('Test: ' . $obj);

        $Event->save();

        return response()->json($request);  
    

    public function deleteEvent($id)
        $Event = Event::find($id);
        $Event->delete();

        return response()->json('deleted');
    

    public function updateEvent(Request $request,$id)
        $Event = Event::find($id);
        $Event->title = $request->input('title');
        $Event->description = $request->input('description');
        $Event->start_time = $request->input('start_time');
        $Event->end_time = $request->input('end_time');
        $Event->save();

        return response()->json($Event);
    


还有 EventModel:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Event extends Model

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
     protected $fillable = ['title', 'description', 'start_time', 'end_time'];

     public function user() 
         return $this->belongsTo('App\User', 'updated_by');
     

     public function category() 
         return $this->belongsTo('App\Category');
     

正如我所说,当我使用 Postman 发送 POST 请求时,一切都按预期工作。但是使用我的 fetch() 函数,我得到了 200 个响应,但是在数据库中只有“created_at”和“updated_at”填充,其余的只是一个空字符串。 EventController 中的 Log-statment 显示,这似乎是 Request-object 是空的。但是查看 Firefox 开发人员工具,我发现数据是在请求正文中发送的。

所以有什么想法吗?如果需要,我也可以发送其他代码文件。

谢谢大家的帮助 马可

编辑:由于不明显,API 和前端都在同一主机上运行; localhost:8000 所以这不是 CORS 问题。我首先在 localhost:8080 上运行前端,但我通过在同一台服务器上运行两者来消除它。

【问题讨论】:

你能检查它是否给出了cors错误吗? 设置模式:"cors" 如果是这样的话 @cauchy 见编辑 可以发一下 Postman 脚本的截图吗? @TarunLalwani 找到了解决方案,但谢谢 【参考方案1】:

果然当没有人真正能够直接回答我的问题时,我的错并不明显。我今天和朋友一起认识到,我实际发送的请求与我在代码中写的不同。 通过更多搜索,我发现我的 webpack.config 以某种方式配置错误并将代码发布在错误的目录中。但是由于已经有一个“旧”的 js 文件,所以页面看起来是正确的,但我的 API-Call 没有变化。

TL;DR 注意一切都在你需要的地方,然后上面的代码是正确的:-)

【讨论】:

以上是关于POST 请求适用于 Postman,但不适用于 axios 或 .fetch()的主要内容,如果未能解决你的问题,请参考以下文章

POST 请求适用于 Postman,但不适用于 axios.post()

请求适用于Postman,但不适用于axios.post

HTTP POST 请求适用于 Postman,但不适用于我的 Web 应用程序的 JavaScript 提取 [关闭]

Multipart POST 适用于 Postman,但不适用于 Angular Http Client

GET 请求适用于 Postman,但为啥它不适用于 ReactJS fetch?

Axios 发布请求适用于 Postman,但不适用于浏览器(它返回“错误 401-未授权”)