ㅡ. 도입

google bigQuery 데이터를 node.js에서 fetch해서 vue.js 로 데이터를 뿌려주는 워크플로우

 

ㅡ. 문제

CORS 문제

node.js에서 express 를 사용하고 있었기 때문에 아래와 같이 cors 패키지를 설치했음에도 

$ npm install --save cors

const cors = require('cors'); //app.js

app.use(cors()); //app.js

Same-origin policy 라는 에러를 뿜어냈습니다. 호스트는 ip + port 를 의미하는데, port 가 달라지면서 (vue.js:8090, node.js:3000) 동일 호스트에서 호출받는 정책이 깨지면서 에러가 발생하였습니다. 즉, 호스트와 오리진이 서로 다른것입니다. 여기서 의미하는 호스트는 요청을 처리하는 서버, api서버를 의미하고 오리진은 요청을 보낸곳의 호스트를 의미합니다. vue.js가 될것입니다. 

(+ same policy 정책은 브라우저에서 임의로 정해준다고 합니다. 브라우저에서 요청시에 헤더를 보관하여 처리하는데 오리진에 요청 보낸곳의 URL를 헤더에 추가한다던지 작업을 수행한다고 합니다. ) 

 

ㅡ. vue.js

import Axios from "axios";
// import store from "../vuex/store.js";
const URL = "http://localhost:3000"


const requestCategoryBasic = (data, callback, errorCallback) =>{
  
    Axios.post(URL + '/bigquery/?category='+data[0])
    .then(response=>{
      callback(response);
      console.log(response)
    }).catch(exp=>{
      console.log(exp)
      errorCallback(exp);
    })

}
const proxyApi = {
  requestCategoryBasic: (data, callback, errorCallback) =>requestCategoryBasic(data, callback, errorCallback),
}
export default proxyApi;

ㅡ. node.js

var express = require('express');
var router = express.Router();
const {BigQuery} = require('@google-cloud/bigquery');



const query=async(res, category)=>{
  // Queries the U.S. given names dataset for the state of Texas.
  const bigquery = new BigQuery();
  const query = "SELECT * FROM `fluid-crane-284202.prototyping_dataset.category_basic` WHERE category="+"'"+category+"'";
  console.log(query)
  console.log(category)
  //const query = "SELECT name FROM \`bigquery-public-data.usa_names.usa_1910_2013\` WHERE state = 'TX' LIMIT 100";
  // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();
  
  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
  
  res.send([rows])

}

/* POST users listing. */
router.post('/', async function(req, res, next) {
  //res.json(users);
  await query(res, req.query.category)
});

module.exports = router;

 

ㅡ. 해결 방법

node.js 란에 아래 코드를 추가하게 되면

res.set({'access-control-allow-origin':'*'});

* 는 ip 를 대신해도 괜찮습니다. * 의미는 전체 호스트의 ip, port 를 허용하겠다 라는 의미입니다. 

ㅡ. ref

https://kamang-it.tistory.com/entry/Web%EB%8F%99%EC%9D%BC-%EC%B6%9C%EC%B2%98-%EC%A0%95%EC%B1%85-CORS-%EB%8F%84%EB%8C%80%EC%B2%B4-%EB%AD%98%EA%B9%8C