不同服务器端口的Node/Express服务器CORS问题



我有一个node/graphql服务器在sitename.com:3333上运行我已经创建了另一个服务器,我正在网站名称上运行:3334

我可以从sitename.com和子域向sitename.com:3333的服务器提出请求。sitename.com

但是,如果我试图从子域连接到sitename.com:3334(只是一个不同的端口(。sitename.com会给我一个cors错误:

阻止跨来源请求:同源策略不允许读取上的远程资源https://sitename.com:3334/graphql.(原因:CORS请求未成功(

我已经打开了防火墙中的端口,并在服务器和客户端上设置了ssl。

请帮忙!

客户端代码如下:

import { ApolloClient } from 'apollo-client'
import { withClientState } from 'apollo-link-state'
import { HttpLink } from 'apollo-link-http'
import { Agent } from 'https'
import fs from 'fs'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
import { onError } from 'apollo-link-error'
import { ApolloLink } from 'apollo-link'
import decode from 'jwt-decode'
import history from '../history'
import Cookies from 'universal-cookie'
import {
APP,
AUTH,
CLIENT_AUTH_REQUEST_TYPE,
CLIENT_AUTHENTICATION_METHOD,
JWT,
VERSION
} from '../environment'
import https from 'https'
import { defaults, resolvers } from '../api'
import { createUploadLink } from 'apollo-upload-client'
const { CONSTANTS: { UNAUTHORIZED, FORBIDDEN } = {} } = APP
const cookies = new Cookies()
const opts = {
credentials: 'same-origin',
headers: {
'frontend-version': VERSION,
[AUTH.STRATEGIES.CLIENT.AUTH_HEADER]: CLIENT_AUTH_REQUEST_TYPE
}
}
const useLocalStorage = CLIENT_AUTHENTICATION_METHOD.LOCAL_STORAGE
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
// const apolloCache = new InMemoryCache();
const apolloCache = new InMemoryCache({
// dataIdFromObject: e => `${e.__typename}_${e.id}` || null // eslint- 
disable-line no-underscore-dangle
})
// const watchedMutationLink = new WatchedMutationLink(apolloCache, 
watchedMutations);
const stateLink = withClientState({
cache: apolloCache,
defaults,
resolvers
})
const uploadLink = createUploadLink({
// uri: 'http://localhost:3333/graphql',
uri: 'https://demo.MYSITE.in:3334/graphql',
fetchOptions: {
agent: new https.Agent()
}
})
const httpLink = new HttpLink({
uri: 'https://demo.MYSITE.in:3334/graphql',
...opts
})
const TOKEN_NAME = 'x-connector-token'
const authLink = new ApolloLink((operation, forward) => {
operation.setContext(({ headers = {} }) => {
const token = cookies.get('token')
if (token) {
headers = { ...headers, 'x-connector-token': token }
}
return { headers }
})
return forward(operation)
})
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors && graphQLErrors.filter(e => e).length > 0) {
graphQLErrors.map(({ message = '', status = 200 }) => {
if (UNAUTHORIZED === message || status === 401) {
if (
history &&
history.location &&
history.location.pathname !== '/login'
) {
history.push('/login')
}
}
if (FORBIDDEN === message || status === 403) {
history.push(`/error-page/403`)
}
return null
})
}
if (networkError && networkError.statusCode === 401) {
// eslint-disable-next-line
history.push('/login')
}
if (networkError && networkError.statusCode === 403) {
// Do something
}
if (networkError && networkError.statusCode === 400) {
// Do something
}
if (networkError && networkError.statusCode >= 500) {
// eslint-disable-next-line
history.push(`/error-page/${networkError.statusCode}`)
}
})
let links = [errorLink, stateLink, httpLink]
links = [
errorLink,
stateLink,
// afterwareLink,
// authMiddlewareLink,
authLink,
// watchedMutationLink,
// httpLink,
uploadLink
]
const link = ApolloLink.from(links)

export default new ApolloClient({
link,
cache: apolloCache,
connectToDevTools: true,
// opts: {
//   agent
// },
fetchOptions: {
agent: new https.Agent()
// rejectUnauthorized: false
},
defaultOptions: {
query: {
errorPolicy: 'all'
}
},
onError: ({ networkError, graphQLErrors }) => {}
})

服务器代码:

const app = express();
// tried this too
const corsOptions = {
origin: 'https://demo.MYSITE.in',
}
// also tried app.use(cors)
app.use(cors({
'allowedHeaders': ['Content-Type'],
'origin': '*',
'preflightContinue': true
}));
app.use(helmet());
// app.use(cors());

浏览器不会向与网页本身来源不同的服务器发出请求(不同的端口构成不同的来源(,除非您在服务器上专门为该新来源启用该请求。这是一个普通的COR问题,有数百万关于如何处理的帖子和文章。由于您在问题中没有显示任何代码,因此我们不建议对您的代码进行特定的代码修复。

您的服务器需要支持您尝试执行的特定CORS请求。如果您使用Express,那么CORS模块在正确实现的情况下会为您做很多工作。CORS是为了保护你的网站,所以从浏览器运行的其他人的网页中的Javascript不能任意使用你的API,所以要小心你向CORS请求打开的内容。

而且,由于这对你来说是一个新问题,我强烈建议你阅读并了解COR是什么以及它是如何工作的。

此外,请注意;简单的";CORS请求和";飞行前请求";(非简单请求(,并且需要更多的工作来启用飞行前请求。浏览器根据请求的确切参数来决定给定的跨来源请求是简单的还是需要预先飞行,您的服务器必须做更多的事情来启用预先飞行的请求。

最新更新