mperdeck / jsnlog.js

Tiny JavaScript logging library, simple and well documented. Lots of options to filter logging data.
js.jsnlog.com
Other
130 stars 43 forks source link

No post body received by server #66

Closed luoshiben closed 6 years ago

luoshiben commented 6 years ago

I'm attempting to set up a very basic scenario where jsnlog captures any uncaught js errors (via try/catch) and sends them to an endpoint on the server. The javascript code is as follows:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jsnlog/2.27.1/jsnlog.min.js" crossorigin="anonymous"></script>
<script>
    JL.setOptions({ defaultAjaxUrl: "/Logger" });
    JL().fatal({ "msg": "test" });
</script>

The server is .NET MVC and endpoint looks like this:

public class LoggerController : Controller
{
    [HttpPost]
    public void Index(string jsonLog)
    {
        var headers = Request.Headers;
        var data = Request.Form;
    }
}

When I debug my project and load the page, the error does fire. However, by inspecting the variables there is no data actually sent to the Index method. The vars jsonLog and Request.Form are null or empty. Sometimes Request.Headers is populated.

Hopefully I'm just making a stupid mistake. Any help is appreciated!

mperdeck commented 6 years ago

You may have to add the [FromBody] attribute to your jsnlog parameter. The log message arrives inside the body of the POST message. Also, it is a JSON object, not a form.

The format of the JSON object is described here: http://jsnlog.com/Documentation/HowTo/LogMessageFormat

The JSNLog nuget package provides an endpoint already. Why do you want to create your own server side endpoint?

luoshiben commented 6 years ago

Thanks for the quick reply. I'm rolling my own endpoint because I need to do some specific things with the log data in relation to the user who generated the client-side error. Fortunately, I figured out what the problem was.

It looks like the reason my route method parameter (or Request.Form) wasn't being populated is because the POST is sent with the content-type of "application/json". For an MVC route with this content type, you need to fetch the POST body from the request stream. Something like:

Stream req = Request.InputStream;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();

Once the raw JSON string is retrieved, you can then use Newtonsoft.Json to deserialize it into a custom object to more easily work with the data.