Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hapi, Error 415 : Unsupported Media Type error

I am trying to send a json object feedData to the server. This object has a File Object inside of it.

feedData = {
    'title' : 'some title',
    'type' : 1,
    'feedBody' : {
        'image' : File Object {lastModified : xxxx, name : 'image.jpg', type: 'image/jpg', ... }
    }
}

return fetch(`/api/feeds/${feedId}/create`, {
    method: 'POST',
    body: JSON.stringify(feedData),
    headers: {
        'Authorization': getTokenHeader(token),
    },
})

In routes I have ,

method: 'POST',
path: '/api/feeds/{feed}/create',
config: {
    payload: {
        output: 'stream',
        parse: true,
        allow: ['application/json', 'multipart/form-data', 'image/jpeg', 'application/pdf', 'application/x-www-form-urlencoded'],
        maxBytes: 1024 * 1024 * 100,
        timeout: false
    },
    handler: (req, res) => {
        const params = { token: req.auth.token, ...req.params };
        const payload = req.payload;
        console.log('HAPI ', payload);
    },
    auth: {
        strategy: 'jwt-strict',
        mode: 'required'
    }
}

I get back an error

http://localhost:3000/api/feeds/feed/create 415 (Unsupported Media Type)

What am I doing wrong?

like image 633
Aman Avatar asked Apr 03 '17 15:04

Aman


3 Answers

I searched and couldn't find the right answer. I seem helpless. But luckily the visua code helped debug the code and I found this line in the index.js@hapi/subtext/lib file

if (contentType.mime === 'multipart/form-data') {
         if (options.multipart === false) {// Defaults to true
             throw Boom.unsupportedMediaType ();
         }


         return await internals.multipart (req, options, source, contentType);
     }

I then fixed multipart = true in router opitions:

{
   payload: {
   maxBytes: 1024 * 1024 * 100,
         // timeout: false, // important
         parse: true,
         output: 'data',
         allow: 'multipart / form-data',
         multipart: true
   }
}

and it worked. Thanks for the visua code debug. I wrote back to someone who might get this error. Know how to handle.

i using hapi version 19.0.3

like image 117
Tran Hoang Hiep Avatar answered Oct 13 '22 10:10

Tran Hoang Hiep


This works for me -

server.route({
  handler: (request: any) =>
    this.uploadProfileImage(request, profileService),
  method: "POST",
  options: {
    auth: "false",
    payload: {
      maxBytes: 1024 * 1024 * 5,
      multipart: {
        output: "file"
      },
      parse: true
    },
    plugins: {
      "hapi-swagger": {
        payloadType: "form"
      }
    },
    tags: ["api", this.controllerName],
    validate: {
      payload: Joi.object({
        image: Joi.any().meta({ swaggerType: "file" })
      })
    }
  },
  path: `/api/${this.controllerName}/upload`
});

And my postman Request is below - enter image description here

like image 32
Biswajit Panday Avatar answered Oct 13 '22 10:10

Biswajit Panday


The following worked,

On Frontend :-

const request = new XMLHttpRequest();
const formData = _getFileFormData(file);

request.open('POST', url);
request.setRequestHeader('authorization', getTokenHeader(token));
request.send(formData);

And on Backend :-

method: 'POST',
path: '/api/feeds/{feed}/create',
config: {
    handler: function (req, res) {
        const pre = preFilter(req.pre);
        const token = req.auth.token;
        const params = { ...req.params, ...pre.params, token: token };
        const payload = req.payload;
        return UploadAction.with(req, res).actionUploadToFeed(params, payload);
    },
    payload: {
        output: 'stream',
        parse: true,
        allow: 'multipart/form-data',
        maxBytes: 1024 * 1024 * 100,
        timeout: false,
    },
    validate: {
        params: {
            ...FeedsController.getValidator(FeedsController.PARAM_CLIENT),
            ...FeedsController.getValidator(FeedsController.PARAM_FEED),
        },
    },
    pre: [
        ...TransformParam.toLowerCase(FeedsController.PARAM_CLIENT),
        ...TransformParam.toLowerCase(FeedsController.PARAM_FEED),
    ],
    auth: {
        strategy: 'jwt-strict',
        mode: 'required',
    },
}
like image 30
Aman Avatar answered Oct 13 '22 10:10

Aman