Tidak Ada 'Akses-Kontrol-Bolehkan-Asal' - Masalah Node / Apache Port


260

Saya telah membuat API kecil menggunakan Node / Express dan mencoba menarik data menggunakan Angularjs tetapi karena halaman html saya berjalan di bawah apache di localhost: 8888 dan simpul API mendengarkan pada port 3000, saya mendapatkan No 'Access-Control- Izinkan-Asal '. Saya mencoba menggunakan node-http-proxydan Vhosts Apache tetapi tidak memiliki banyak keberhasilan, silakan lihat kesalahan penuh dan kode di bawah ini.

XMLHttpRequest tidak dapat memuat localhost: 3000. Header 'Access-Control-Allow-Origin' tidak ada pada sumber daya yang diminta. Karena itu, 'localhost: 8888' tidak diizinkan mengakses. "

// Api Using Node/Express    
var express = require('express');
var app = express();
var contractors = [
    {   
     "id": "1", 
        "name": "Joe Blogg",
        "Weeks": 3,
        "Photo": "1.png"
    }
];

app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')

Kode sudut

angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').then(function(response) {
       var data = response.data;
       $scope.contractors = data;
   })

HTML

<body ng-app="contractorsApp">
    <div ng-controller="ContractorsCtrl"> 
        <ul>
            <li ng-repeat="person in contractors">{{person.name}}</li>
        </ul>
    </div>
</body>

Jawaban:


622

Coba tambahkan middleware berikut ke aplikasi NodeJS / Express Anda (saya telah menambahkan beberapa komentar untuk kenyamanan Anda):

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

Semoga itu bisa membantu!


2
Bisakah Anda membantu menentukan dengan tepat ke mana perginya? Saya memiliki kode berikut di server saya. Apakah setelah ini? var app = require ('express') (), server = require ('http'). createServer (app), io = need ('socket.io'). dengarkan (server), request = butuhkan ("request") , url = butuhkan ("url"); server.listen (6969); // apakah itu di sini? pada baris baru?
Seni Geigel

1
@jvandemo apakah saya harus mengubah app.get ('/', function (req, res) menjadi ... function (req, res, next)?
Sangram Singh

10
Anda adalah orang favorit saya saat ini. Terima kasih. Bisakah kita menambahkan catatan bahwa kode ini harus terjadi sebelum rute ditetapkan untuk noobs seperti saya?
gegillam

1
Bagaimana cara membuatnya bekerja saat menggunakan modul permintaan?
Rohit Tigga

2
Tidak berhasil dalam kasus saya. Masih mendapatkan kesalahan ini: "Respons terhadap permintaan preflight tidak lulus pemeriksaan kontrol akses: Tidak ada tajuk 'Akses-Kontrol-Bolehkan-Asal' hadir pada sumber daya yang diminta. Karena itu, Asal ' abc.xyz.net:12 ' tidak diizinkan akses. Responsnya memiliki kode status HTTP 500. "
user1451111

96

Jawaban yang diterima baik-baik saja, jika Anda lebih suka sesuatu yang lebih pendek, Anda dapat menggunakan plugin bernama cors yang tersedia untuk Express.js

Sangat mudah digunakan, untuk kasus khusus ini:

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));

3
Saya harus menggunakannya {origin: 'null'}agar berfungsi ... Ternyata, peramban saya mengirim nullsebagai asal?
Ricardo Cruz

2
Mengapa menemukan kembali roda. Saya selalu untuk solusi paket dibandingkan dengan cuplikan kode
Pierre

perpustakaan kecil yang manis yang menangani kasus penggunaan saya menginginkan metode yang berbeda dari asal yang berbeda dengan cukup baik ... dan kurang kelelahan kode untuk orang berikutnya yang melihatnya.
Kyle Baker

6
Terima kasih, app.use(cors({origin: '*'}));bekerja untuk saya, sesuai aktif-kor .
danialk

2
Saya sarankan melihat- lihat halaman npm cors untuk memanfaatkannya dengan lebih baik. Itu membuat segalanya sangat jelas bagi saya =).
13013SwagR

30

Cara lain, cukup tambahkan header ke rute Anda:

router.get('/', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
    res.setHeader('Access-Control-Allow-Credentials', true); // If needed

    res.send('cors problem fixed:)');
});

8
)dari smiley membingungkan saya
diEcho

17

The top jawaban bekerja dengan baik bagi saya, kecuali bahwa saya perlu daftar putih lebih dari satu domain.

Juga, jawaban teratas menderita dari kenyataan bahwa OPTIONSpermintaan tidak ditangani oleh middleware dan Anda tidak mendapatkannya secara otomatis.

Saya menyimpan domain yang masuk daftar putih seperti allowed_originspada konfigurasi Express dan meletakkan domain yang benar sesuai dengan origintajuk karena Access-Control-Allow-Origintidak mengizinkan menentukan lebih dari satu domain.

Inilah yang akhirnya saya dapatkan:

var _ = require('underscore');

function allowCrossDomain(req, res, next) {
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

  var origin = req.headers.origin;
  if (_.contains(app.get('allowed_origins'), origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

  if (req.method === 'OPTIONS') {
    res.send(200);
  } else {
    next();
  }
}

app.configure(function () {
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(allowCrossDomain);
});

Apakah ini sama 'jika (app.get (' asal diperbolehkan '). IndexOf (asal)! == - 1)?'?
Rune Jeppesen

13

Kode jawaban hanya memungkinkan untuk localhost: 8888. Kode ini tidak dapat digunakan untuk produksi, atau nama server dan port yang berbeda.

Untuk membuatnya berfungsi untuk semua sumber, gunakan ini sebagai gantinya:

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

2
Ini tidak bekerja untuk saya! "* bukan asal yang valid". Tampaknya karakter * tidak dikenali sebagai wildcard.
Francesco

Ini bekerja untuk saya. yaitu menggunakan kartu liar '*'. berfungsi baik untuk chrome dan safari.
AnBisw

Terima kasih;) Berfungsi dengan baik
Mauro

9

Instal dependensi kor di proyek Anda:

npm i --save cors

Tambahkan ke file konfigurasi server Anda berikut ini:

var cors = require('cors');
app.use(cors());

Ini bekerja untuk saya dengan versi 2.8.4 cors.


"cors": "^2.8.5", "express": "^4.16.3",berfungsi dengan baik hanya dengan garis yang disarankan @monikaja. Terima kasih!
RamiroIsBack

Apa yang dilakukan adalah mengaktifkan semua sumber / domain untuk mengakses aplikasi yang biasanya tidak ingin Anda lakukan. Alih-alih, tentukan hanya domain yang diizinkan.
Lacho Tomov

7

Ini berhasil untuk saya.

app.get('/', function (req, res) {

    res.header("Access-Control-Allow-Origin", "*");
    res.send('hello world')
})

Anda dapat mengubah * agar sesuai dengan kebutuhan Anda. Semoga ini bisa membantu.


7

Hai ini terjadi ketika ujung depan dan belakang berjalan pada port yang berbeda. Browser memblokir respons dari backend karena tidak adanya header CORS. Solusinya adalah dengan membuat menambahkan header CORS dalam permintaan backend. Cara termudah adalah dengan menggunakan paket nors cpm.

var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())

Ini akan memungkinkan tajuk CORS di semua permintaan Anda. Untuk informasi lebih lanjut, Anda dapat merujuk ke dokumentasi kor

https://www.npmjs.com/package/cors


3
app.all('*', function(req, res,next) {
    /**
     * Response settings
     * @type {Object}
     */
    var responseSettings = {
        "AccessControlAllowOrigin": req.headers.origin,
        "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",
        "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
        "AccessControlAllowCredentials": true
    };

    /**
     * Headers
     */
    res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
    res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);
    res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
    res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);

    if ('OPTIONS' == req.method) {
        res.send(200);
    }
    else {
        next();
    }


});

2

Tambahkan kode berikut di app.js dari NODEJ Restful api untuk menghindari kesalahan "Access-Control-Allow-Origin" di sudut 6 atau kerangka kerja lainnya

var express = require('express');
var app = express();

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

1

Anda dapat menggunakan "$ http.jsonp"

ATAU

Di bawah ini adalah pekerjaan untuk chrome untuk pengujian lokal

Anda perlu membuka krom Anda dengan perintah berikut. (Tekan jendela + R)

Chrome.exe --allow-file-access-from-files

Catatan: Chrome Anda tidak boleh terbuka. Ketika Anda menjalankan perintah ini chrome akan terbuka secara otomatis.

Jika Anda memasukkan perintah ini di command prompt kemudian pilih direktori instalasi chrome Anda kemudian gunakan perintah ini.

Di bawah kode skrip untuk chrome terbuka di MAC dengan "--allow-file-access-from-file"

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"

opsi kedua

Anda bisa menggunakan open (1) untuk menambahkan flag: open -a 'Google Chrome' --args --allow-file-access-from-files


Bagaimana dengan MAC ?? Chrome.exe --allow-file-access-from-files
user1336103

/ Aplikasi / Google \ Chrome.app/Contents/MacOS/Google \ Chrome --allow-file-access-from-file berhasil membuka chrome tetapi pesan masih menunjukkan "XMLHttpRequest tidak dapat memuat localhost: 3000. Origin localhost: 8888 adalah tidak diizinkan oleh Access-Control-Allow-Origin. "
user1336103

+1 Saya dapat mengonfirmasi ini berfungsi dengan opsi Mac menggunakan 'terbuka'. Kasus saya sedikit berbeda karena saya hanya menguji situs yang sepenuhnya diunduh yang mengakses beberapa file JSON lokal.
spong

0

/**
 * Allow cross origin to access our /public directory from any site.
 * Make sure this header option is defined before defining of static path to /public directory
 */
expressApp.use('/public',function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    // Request headers you wish to allow
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // Set to true if you need the website to include cookies in the requests sent
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
});


/**
 * Server is about set up. Now track for css/js/images request from the 
 * browser directly. Send static resources from "./public" directory. 
 */
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.