[Vuejs]-Getting an internal server error when I try to make a request to a Seneca.js API using Axios

3👍

Yup, tested locally and your problem indeed seems to be with Stringify, as mentioned in my comment, just send the data directly:

axios.post('http://localhost:10101/act', this.postBody)

1👍

The curl does not work otherwise, you just do not pass the desired header in the query. The bottom line is that the server should understands in which format it should receive data. I see that in your code you give JSON. Therefore, specify the format of the transmitted data via the header.

For example, you should such request:

curl -H "Content-Type: application/json" localhost:10101/act

Your server (backend) must respond with exactly the same header.

Problem a CORS – problem a server. If you have problem with CORS, in your case, I think that your frontend works on a different port in contrast to api. In any case, you do not need to transfer the header for the CORS on the front-end side (although someone is trying to do this and usually it’s a waste of time). You just need to monitor the type of data transmitted.

See example Axios get/post (never mind):

const configAxios = {
  headers: {
    'Content-Type': 'application/json',
  },
};
axios.post('api/categories', configAxios)
  .then((res) => {
    this.categories = res.data;
    console.log(res);
  })
  .catch((err) => {
    console.warn('error during http call', err);
  });

In your code you use JSON.stringify, don’t do it, because Axios already use this features.

Server side

For example server-side. I like Symfony4 and it is used NelmioCorsBundle, look at the allow_origin: ['*']. It’s pretty simple, if you use Symfony.

nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: ['*']
        allow_headers: ['Content-Type']
        allow_methods: []
        expose_headers: []
        max_age: 0
        hosts: []
        origin_regex: false
        forced_allow_origin_value: ~
    paths:
        '^/api/':
            allow_origin: ['*']
            allow_headers: ['X-Custom-Auth', 'Content-Type', 'Authorization']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
            max_age: 3600
        '^/':
            origin_regex: true
            allow_origin: ['^http://localhost:[0-9]+']
            allow_headers: ['X-Custom-Auth', 'Content-Type']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
            max_age: 3600
            hosts: ['^api\.']

If you are not directly working with the server, then check with your supplier for this nuance.

This header can also be transmitted for example through Nginx, which is not the best idea.

For example, look at the:

add_header Access-Control-Allow-Origin *;

server {
    listen 8080;
    server_name site.local;
    root /var/www/site/public;

    location / {
	      add_header Access-Control-Allow-Origin *;

        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;	
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/index.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    # return 404 for all other php files not matching the front controller
    # this prevents access to other php files you don't want to be accessible.
    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}

It is worth paying attention if there is no data passed it removes the Content-Type. The data must always be transmitted or be null. This is strange and it is misleading.

1👍

The following code has many issues:

var body = JSON.stringify(this.postBody)
axios.post(`http://localhost:10101/act`, {
  body: body
})

First, axios.post() returns a Promise. If your method is meant to be asynchronous, you should either await axios.post(…) and mark your method async or return axios.post(…).

Second, if you see the axios docs for axios.post(), the second parameter is the postData itself. What you have instructed AXIOS to do is send this JSON as the body:

{"body":"{\\"id\\":\\"12\\",\\"role\\":\\"buyer\\",\\"action\\":\\"acceptOffer\\"}"}

i.e., you are 1. wrapping the object you intend to send in yet another object 2. double-stringifying the data. Consider the result of parsing it once (which seneca will do for you):

> JSON.parse(s)
{ body: '{"id":"12","role":"buyer","action":"acceptOffer"}' }

The above data with the body key being a string is what Seneca is being sent and what you will have to create a handler for. Within your handler, you will have to unescape body again:

> JSON.parse(JSON.parse(s).body)
{ id: '12', role: 'buyer', action: 'acceptOffer' }

However, I do not know why this would cause an error with Seneca.js itself. It’s likely that seneca is throwing the error because you have not set any handlers for the the pattern where there is a body property with a string value. Maybe if you do something like this (I don’t know how to accept a string value as a pattern in seneca, this is probably wrong):

this.add('body:string', function(msg, respond){respond({value: msg.body})});

Guesses

Maybe you intended to write your axios call passing the unescaped data so that it gets encoded to JSON by axios properly:

var body = this.postBody; // Note *NOT USING JSON.stringify()*
axios.post('http://localhost:10101/act', body); // Note *NOT PASSING body KEY*

and in your handler you shouldn’t double encode the result either (probably, unsure about how seneca works):

module.exports = function buyer (){
    this.add('role:buyer, action: acceptOffer', function(msg, respond){
        respond({answer: msg.id}) // Note *NOT USING JSON.stringify*
    })
}
👤binki

0👍

your axios request header must contain

header {
    'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8;application/json'
}

This works for me.

Leave a comment