简体   繁体   English

带有“表单数据”类型的请求正文参数的POST不起作用+角度2

[英]POST with request body params of type 'form-data' not working + angular 2

I am sending a file and other parameters in body with type 'form-data' in postman and it works fine. 我在邮递员中使用'form-data'类型在正文中发送文件和其他参数,并且工作正常。 I want to do the same in angular 2. Please find the snapshot of the request in postman: 我想在角度2中做同样的事情。请在邮递员中找到请求的快照: 在此处输入图片说明

Also, find my non-working angular code. 另外,找到我无法使用的角度代码。 What is wrong with that: 这有什么问题:

let formData: FormData = new FormData();
        formData.append('file', file);
        formData.append('pid', 2);
        formData.append('cid', 4);
        let headers = new Headers();
        headers.append('Authorization', '5C7D01DD-95F5-44CA-B897-012B218D80012');
        let requestOptions = new RequestOptions({ headers: headers });
        console.log('API call: to upload lead file');
        return this.http.post("http://blahblha.com" + LeadApi, formData, requestOptions)
            .retryWhen((error) => error.delay(this.appConfig.serviceCallRetryDelay))
            .timeout(this.appConfig.serviceCallRetryTimeOut)
            .map((response: Response) => response.json());

I am getting Error 500- Internal Server Error

Also, attached is the request payload from Network: 另外,附有来自网络的请求有效负载:

------WebKitFormBoundaryzbq2nbK8gMNeqBck
Content-Disposition: form-data; name="file"; filename="Testleads.csv"
Content-Type: application/vnd.ms-excel


------WebKitFormBoundaryzbq2nbK8gMNeqBck
Content-Disposition: form-data; name="pid"

2
------WebKitFormBoundaryzbq2nbK8gMNeqBck
Content-Disposition: form-data; name="cid"

4
------WebKitFormBoundaryzbq2nbK8gMNeqBck--

What am i doing wrong in angular2?? 我在angular2中做错了什么?

Create an Angular2 Service first, so you can access it and just call methods when you need to get or post data. 首先创建一个Angular2服务,以便您可以访问它,并在需要获取或发布数据时仅调用方法。

Service: 服务:

@Injectable()
export class ApiService {
    private headers = new Headers({'Content-Type': 'application/form-data; charset=UTF-8'});

    constructor(private http: Http) {
    }

    public send(url, body: Object): Observable<any> {
        let bodyString = this.serializeObj(body);

        return this.http
            .post(url, bodyString, {headers: this.headers})
            .map(this.extractData)
            .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        if (body) {
            return body.data || body;
        } else {
            return {};
        }
    }

    private handleError(error: any) {
        // In a real world app, we might use a remote logging infrastructure
        // We'd also dig deeper into the error to get a better message
        let errMsg = (error.message) ? error.message :
            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }

    private serializeObj = function (obj, prefix = null) {
        let str = [], p;
        for (p in obj) {
            if (obj.hasOwnProperty(p)) {
                let k = prefix ? prefix + '[' + p + ']' : p, v = obj[p];
                str.push((v !== null && typeof v === 'object') ?
                    this.serializeObj(v, k) :
                    encodeURIComponent(k) + '=' + encodeURIComponent(v));
            }
        }
        return str.join('&');
    };
}

In your component: 在您的组件中:

constructor(private apiService: ApiService) {
    let mySendingObject = {}; // This is the object you send in your POST
    this.sendData(mySendingObject); // And here we are actually calling our method that uses the post method within ApiService
}

sendData(myObj) {
   let url = 'http://blahblha.com' + LeadApi;
   return this.apiService.send(url, myObj);
}

Where you need to send your post, just call inside your component the method sendData() . 在需要发送帖子的地方,只需在组件内部调用sendData()方法sendData()

This way you have several things achieved: 通过这种方式,您可以实现以下几点:

  • You separated your api service from the rest of your App 您将api服务与应用程序的其余部分分离了
  • You can create a more specific service that imports the ApiService . 您可以创建导入ApiService的更特定的服务。 For example: UserService that imports and uses ApiService 例如:导入并使用ApiService UserService
  • We have methods that: 我们有以下方法:
    • Handle error in calls: handleError() 处理调用中的错误: handleError()
    • Extract the data: extractData() 提取数据: extractData()
    • Serialize objects: serializeObj() 序列化对象: serializeObj()

The structure should be like: 结构应类似于:

  • ApiService : manages the API calls with Http (post, get, etc) ApiService :使用Http管理API调用(发布,获取等)
    • Local service, example: UserService : imports the ApiService and has methods such as: updateUser , deleteUser , addUser ... For example. 本地服务,例如: UserService :导入ApiService并具有诸如: updateUserdeleteUseraddUser等方法。
      • The component, example: UsersViewComponent : Uses the UserService and interacts with it through the view . 组件,例如: UsersViewComponent :使用UserService并通过view与之交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM