I'm using the ajax_links_api module to "ajaxify" a certain menu. When a menu button is clicked, the corresponding node loads into a specified div via ajax. This works well.

The problem is that the nodes I want to load in this way should not be accessible as pages. I often create Drupal content that is only designed to appear in views, or as related content on other pages and is not supposed to be displayed by itself. My method is to use .htaccess to block these pages. But when I do that, the ajax can't access them either.

Is there a way to block access to pages in a browser but to allow requests coming from Drupal itself? Localhost access is not really an option since the site may well end up spread across different servers and virtual machines.

If not, then can someone recommend an alternative to the ajax links module - perhaps I need to write some custom ajax that triggers Drupal to serve up a node "directly" rather than via a page - but I am confused about this and could use some pointers in the right direction. I must admit I find the "example" modules confusing!

EDIT: I've tried making a custom module as David Thomas suggests below and using hook_node_access. However this stops the ajax call from returning the content.

  • Can you post some of your code? Feb 18, 2014 at 2:00
  • Thanks David but I think the problem is that the ajax_links_api module is not flexible enough for what I want to do. I've had another look at some ajax examples and will try rolling my own ajax stuff.
    – naomi
    Feb 18, 2014 at 9:02
  • Edited to make it clear that the problem I had was with a specific contrib module, not the core Drupal ajax functionality
    – naomi
    Feb 19, 2014 at 13:16

3 Answers 3


You could use RabbitHole module:

Rabbit Hole is a module that adds the ability to control what should happen when an entity is being viewed at its own page.

Perhaps you have a content type that never should be displayed on its own page, like an image content type that's displayed in a carousel. Rabbit Hole can prevent this node from being accessible on its own page, through node/xxx.


You can control access to nodes with


For example, to restrict node viewing on node/[nid] pages:

 * Implements hook_node_access
function MYMODULE_node_access($node, $op, $account) {

  // If viewing node and URL path is node/[nid]
  // where [nid] is current $node->nid
  if($op == 'view' && arg(0) == 'node' && arg(1) == $node->nid){
    // Deny access to view current node page
    return NODE_ACCESS_DENY;


You can add your own conditions to get more specific about access control there.

If you want to deny access to all node/%node/view pages, you can do it quite simply with:


For example, set the access callback to FALSE

 * Implements hook_menu_alter
function MYMODULE_menu_alter(&$items) {
  // Disable the node view page at node/%node
  $items['node/%node']['access callback'] = FALSE;
  • yes,good and suitable solution (y)
    – Yuseferi
    Feb 17, 2014 at 10:55
  • Sorry, this does not seem to work. The ajax call just returns "You are not authorized to access this page".
    – naomi
    Feb 17, 2014 at 15:00
  • You haven't specified any code or how you're making the ajax calls. You'll need to add the appropriate conditional check in hook_node_access. It's core functionality. It will work. Feb 17, 2014 at 19:44
  • Hi, it seems you misunderstood my question. I am using a contrib module called ajax_links_api that allows you to ajaxify links without writing any code.
    – naomi
    Feb 19, 2014 at 13:15

I hope I am not too late to try and answer this question... I ran into it because I am in the exact same position as the author...

Well, the difference is I make an ajax call with jQuery's load(). And yes, when I take the href of the node page I get 403 (Forbidden).

But, firstly let me explain my kind of set!

I don't use any modules for restricting access to node content... You see I randomly (again) ran into a video and saw sth that guy did extremely genious (sorry, I wish I could endorse him... didn't bookmark it):

When he created a new content type eg. a slider and because he didn't want to theme the node page (it was a photo and a link!! Why bother?) he unchecked (oh man! God bless you!) the Published default option in the content type edit page. GENIOUS!! It's on top of Promoted to first page etc... So, no Rabbit holes and internal pages modules needed... Users anonymous etc. see 403 when viewing content... And you could change permissions etc. etc. Perfect!! Now, with the new knowledge I have by default restriction to unthemed nodes...

And you might ask! With Views? How I display nodes? EASY: remove Content: Published filter... WOW!! We are set to go!!

But, then ajax call came... I had node page hrefs for the url parameter of ajax call... And, while unpublished I got 403 errors... The thing is I had already made big progress with theming etc. and left it for the end!! Looking desperately for a solution with no refactoring big changes in code and CSS... And I published my content type... So, the bug is this... if someone right clicks and open link in new tab sees... well a mess (in comparison with the other site... I themed it as better as I could... hahahaha)!!

And, then came the lighting (too late of course for me to follow... I don't have enough time right now):

I should have left Content type unpublished and make a new view page... So, when my load() function took the url as input that would show my unpublished-restricted node without problem... Of course, I should rewrite output etc... Instead of /node/id I would have sth like if my content-type was article -> articles/nid...

I hope this helps someone!! Cheers...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.