Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use InfluxDB 1.8 directly from the browser #199

Closed
cailloumajor opened this issue Jun 8, 2020 · 9 comments
Closed

Unable to use InfluxDB 1.8 directly from the browser #199

cailloumajor opened this issue Jun 8, 2020 · 9 comments
Milestone

Comments

@cailloumajor
Copy link

Background

I am developing a web application based on Vue.js (client-side) that needs to query InfluxDB 1.8 at regular interval, using Flux. The application reaches InfluxDB directly by http://host:port. I first tried to use this library (version 1.4.0-nightly.14) as in examples/influxdb-1.8.ts, but I couldn't make it work due to CORS preflight not acknowledged by InfluxDB (v1.8.0).
I then decided to use @influxdata/influxdb-client-apis (version 1.3.0) to do the query (using QueryAPI.postQuery), with the code below:

(note the usage of { mode: "no-cors" } as postQuery's request options, intended for fetch call, and which raises a typing error)

import { flux, InfluxDB } from "@influxdata/influxdb-client"
import { QueryAPI } from "@influxdata/influxdb-client-apis"
import { Plugin } from "vuex"

import { automation } from "../modules/automation"

export default function createVuexPlugin(
  url: string,
  DBName: string
  // eslint-disable-next-line
): Plugin<any> {
  return store => {
    const ctx = automation.context(store)
    const influxDB = new InfluxDB({ url })
    const queryAPI = new QueryAPI(influxDB)
    const bucket = `${DBName}/autogen`
    const query = flux`\
      from(bucket: "${bucket}")
        |> range(start: -1d)
        |> increase()
        |> yield()`.toString()

    function influxQuery() {
      queryAPI
        .postQuery(
          { body: { query } },
          // eslint-disable-next-line
          // @ts-ignore
          { mode: "no-cors" }
        )
        .then((value: string) => console.log(value))
    }

    window.setInterval(influxQuery, 10000)
  }
}

The query now fulfills, but I receive an disappointing undefined string as the result of the succeeding Promise ! (see below the console of Firefox Developer Edition)
image

The response from InfluxDB seems to be conform:
image

Description of the problem

For a reason I don't understand, commit d106c08 made Content-Type header name all-lowercase (and I fear other cases like this were introduced later, eg. accept-encoding 1c9ba45), IMHO preventing them to being correctly interpreted by browsers and InfluxDB (see below, showing that Content-Type: application/json is not sent to InfluxDB, despite the intention in QueryAPI.postQuery).
image
For the case described in this issue, this makes responseContentType below always equal to empty string, making the whole function return undefined.

async request(path: string, body: any, options: SendOptions): Promise<any> {
const response = await this.fetch(path, body, options)
const {status, headers} = response
const responseContentType = headers.get('content-type') || ''
let data = undefined
try {
if (responseContentType.includes('json')) {
data = await response.json()
} else if (responseContentType.includes('text')) {
data = await response.text()
}
} catch (_e) {
// ignore
Logger.warn('Unable to read error body', _e)
}
if (status >= 300) {
throw new HttpError(
status,
response.statusText,
data,
response.headers.get('retry-after')
)
}
return data
}

Additional thoughts

This issue makes me being in trouble, because it prevents the whole library from being usable in my use case, this one not being an edge case IMHO.
Does anyone have an idea about the CORS preflight problem described at the beginning ?

@sranka
Copy link
Contributor

sranka commented Jun 8, 2020

@cailloumajor the browser example works fine when used against a proxy and it does not when using CORS. The v1 server code does not handle CORS as v2 does, so it is blocked by the client. I am on the way to find a workaround.

@sranka
Copy link
Contributor

sranka commented Jun 8, 2020

I found out that CORS is not supported in "v2 compatibility endpoints" of InfluxDB v1, this is now reported in influxdata/influxdb#18391 .

Using a proxy that would satisfy CORS requirements or running a browser to ignore CORS requirements is a workaround. I am now looking deeper at your workaround @cailloumajor

@sranka
Copy link
Contributor

sranka commented Jun 8, 2020

Regarding your workaround @cailloumajor . The "no-cors" mode allows only limited settings of content-type, "application/json" is not allowed ... that's why your FF sends text/plain. Additionally, in the 'no-cors' mode, fetch returns an opaque response so the code cannot see response headers and even body.

@cailloumajor
Copy link
Author

@sranka thank you for those informations, and sorry for wrongly focusing on headers names case.

I am going to try using a proxy in my project, it was planned for production but it seems I need it in development too...

@sranka sranka changed the title Library unusable in browser environment with InfluxDB 1.8 Unable to query InfluxDB 1.8 directly from the browser, CORS not supported Jun 8, 2020
@sranka sranka changed the title Unable to query InfluxDB 1.8 directly from the browser, CORS not supported Unable to query InfluxDB 1.8 directly from the browser Jun 8, 2020
@sranka sranka changed the title Unable to query InfluxDB 1.8 directly from the browser Unable to query InfluxDB 1.8 directly from the browser (CORS) Jun 8, 2020
@sranka sranka changed the title Unable to query InfluxDB 1.8 directly from the browser (CORS) Unable to use InfluxDB 1.8 directly from the browser Jun 8, 2020
@sranka
Copy link
Contributor

sranka commented Jun 8, 2020

You are welcome @cailloumajor , The actual issue is influxdata/influxdb#18391.

@jitendracodehacker
Copy link

jitendracodehacker commented Nov 26, 2020

@sranka : i am also facing the CORS issue when i use the example code in my browser.

// https://v2.docs.influxdata.com/v2.0/reference/syntax/annotated-csv/

queryApi.queryRows(fluxQuery, {
  next(row: string[], tableMeta: FluxTableMetaData) {
    const o = tableMeta.toObject(row)
    // console.log(JSON.stringify(o, null, 2))
    console.log(
      `${o._time} ${o._measurement} in '${o.location}' (${o.example}): ${o._field}=${o._value}`
    )
  },
  error(error: Error) {
    console.error(error)
    console.log('\nFinished ERROR')
  },
  complete() {
    console.log('\nFinished SUCCESS')
  },
})

@sranka
Copy link
Contributor

sranka commented Nov 26, 2020

Thank you @jitendracodehacker for letting us know, it depends on whether your InfluxDB contains a fix for influxdata/influxdb#18391 , AFAIK there is no public 1.8 release with this fix yet. The client example uses a proxy to workaround 1.8 CORS issues.

@jitendracodehacker
Copy link

jitendracodehacker commented Nov 27, 2020

Thank you .. but still i am facing the issue. here is the output of my node proxy server
image

could you check this .

my setup is :
i have running angular application on my machine and influx db is deployed to AWS EC2 instance.

@sranka
Copy link
Contributor

sranka commented Nov 27, 2020

It should be fine if your angular app is served from the same server where the proxy is running, no CORS is then used. You can also add cors to the proxy server, so that the proxy can be accessed from any origin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants