SchoolUtils / WebUntis

JavaScript WebUntis API Client
https://webuntis.noim.me/
MIT License
159 stars 21 forks source link

Network Error / Refused to set unsafe header "User-Agent" #57

Closed derkrasseleo closed 2 years ago

derkrasseleo commented 2 years ago

I am trying to use the WebUntis API in a React Native / TypeScript project on Stackblitz, but it keeps throwing this network error and I have no clue why.

image

I don't know if this has to do with the API, because I am new to react and APIs, so any help would be appreciated.

TheNoim commented 2 years ago

This is not an issue with WebUntis or the API itself. This is how Content Security in browsers work. You can't access api routes from a foreign host except if he allows it. However, you can try to set https://github.com/SchoolUtils/WebUntis/blob/master/index.js#L25 manual and add a CORS proxy.

For example (untested):

// untis is your untis api instance
untis.baseurl = "https://crossorigin.me/" + untis.baseurl;
derkrasseleo commented 2 years ago

Thank you for the answer.

I am setting the base URL here (which should be the same, right?): image

Unfortunately, I still get the same error when using crossorigin.

It works with mese.webuntis.com when I use it locally with node, so I don't know what's wrong here.

derkrasseleo commented 2 years ago

Oops, the first https:// shouldn't be there..

Update:

New error: image

TheNoim commented 2 years ago

I could provide an option which disables the user agent.

derkrasseleo commented 2 years ago

That would be great but would that fix my issue? Because I don't know what to do at that point..

TheNoim commented 2 years ago

That would be great but would that fix my issue? Because I don't know what to do at that point..

I can't promise it. But maybe it will. At least it will fix the User Agent error.

TheNoim commented 2 years ago

I published a new version with the disableUserAgent option:

Screenshot 2022-01-16 at 01 12 51

derkrasseleo commented 2 years ago

I appreciate the effort! But for me, it didn't fix the problem. Neither with crossorigin nor without.

TheNoim commented 2 years ago

Which problem still persist?

TheNoim commented 2 years ago

Or better, can you provide a project for reproduction?

derkrasseleo commented 2 years ago

I still get these errors: image

This is what the console on stackblitz says: image

Here's my code, broken down to the bare minimum:

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

const WebUntis = require('webuntis');

interface AppProps {}
interface AppState {
  endTime: string;
}

const untis = new WebUntis(
  'school',
  'user',
  'passwd',
  'mese.webuntis.com/',
  'Stackblitz',
  'true'
);

let endTime: string;
let day = new Date(2022, 0, 17);

async function getLastLesson(day: Date) {
  console.log('getLastLesson');
  try {
    await untis
      .login()
      .then(() => {
        console.log('1');
        return untis.getOwnTimetableForRange(day, day);
      })
      .then((timetable) => {
        timetable.sort((a, b) => a.startTime - b.startTime);
        let endTime = WebUntis.convertUntisTime(
          timetable[timetable.length - 1].endTime,
          new Date()
        );
        return endTime;
      })
      .then((endTime) => {
        try {
          console.log('Success');
          console.log(endTime);
        } catch (error) {
          endTime = 'Error';
          console.log(error);
        }
      });
  } catch (error) {
    console.log(error);
  }
}

getLastLesson(day);

class App extends Component<AppProps, AppState> {
  constructor(props) {
    super(props);
    this.state = {
      endTime: endTime,
    };
  }

  render() {
    return (
      <div>
        <p>Last lesson is at: {this.state.endTime}</p>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));
TheNoim commented 2 years ago

But why are you not using the crossorigin proxy anymore? Without it, it will never work inside of a web browser.

derkrasseleo commented 2 years ago

With crossorigin:

image

derkrasseleo commented 2 years ago

I also tried two other CORS proxies (thingproxy and alloworigin) but that only made it worse.

TheNoim commented 2 years ago

Ok, I tested it locally and now I know what the issue is. It seems like there is no good public available CORS proxy anymore. Most of them faced too much abuse. You now have only two options:

  1. Host your own CORS proxy and use it instead of crossorigin.me. crossorigin.me doesn't even exist anymore, this is why the request fails. You can use this https://github.com/Rob--W/cors-anywhere to setup your own CORS proxy
  2. You do all WebUntis requests on server side with nodejs
TheNoim commented 2 years ago

I also tried two other CORS proxies (thingproxy and alloworigin) but that only made it worse.

Most of them get disqualified, because they do not support everything what webuntis needs https://gist.github.com/jimmywarting/ac1be6ea0297c16c477e17f8fbe51347

derkrasseleo commented 2 years ago

Well, that's sad. I don't think these solutions are right for me, as I don't have the option to self-host. But thank you for everything!

TheNoim commented 2 years ago

When somebody ever needs this:

I tested a local version of https://github.com/Rob--W/cors-anywhere This works fine.

To make it work with http for local testing, you need to do this

// Untis instance
untis.baseurl = `http://` + YOUR_BASE_URL;
// Update the axios instance
untis.axios = untis.axios.create({ baseURL: untis.baseurl });